Есть ли способ очистить рабочее пространство Jenkins Worflowjob с помощью отличного сценария через консоль сценариев Jenkins?

Почему снова такой вопрос?

Этот вопрос, кажется, задавали несколько раз, но все ответы актуальны для заданий Jenkins Pipeline (плагин: workflow-job).

Ситуация

Я переношу кучу старых фристайл-заданий со старого автономного сервера Jenkins на распределенный Jenkins env, и я решил преобразовать их в задания Jenkins Pipeline (нельзя использовать Blue ocean для этого как SCM - это SVN.

В любом случае, для некоторых заданий нежелательно очищать свои рабочие пространства, поскольку они являются своего рода заданиями для проверки работоспособности / проверки и из-за того, что размер проверки SVN и встроенного материала велик (2 ГБ в файлах 20K, просто удаление происходит очень медленно).

Тем не менее, мне время от времени (время от времени) нужно удалить рабочую область таких заданий. И я не хочу делать это следующими способами:

И у меня нет прямого доступа к FS на этом подчиненном узле (что было бы проще всего).

Поиск в Google

Быстрый поиск в Интернете обрушился на меня с десятками результатов [1, 2 , 3, 4, ...] как очиститьWS () из сценария Groovy, запущенного из консоли сценария Jenkins.

К сожалению, ни один из них не пытается удалить рабочую область истинного org.jenkinsci.plugins.workflow.job.WorkflowJob экземпляра элемента задания.

Моя попытка Groovy очистить WS

Основываясь на ответах, полученных из Интернета, я запустил свой скрипт очистки Groovy, который можно запустить из консоль сценария Jenkins <Jenkins:port/script>

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)

Просто потому, что эти методы недоступны для этого типа элементов, а только для _7 _

Вопрос: Как тогда я могу удалить рабочую область задания Pipeline?

Существует еще один плагин Jenkins: Workspace Cleanup, который, вероятно, используется в Jenkinsfile, вызывая cleanWs() внутри stage() {}, но я не понял, как использовать его извне Jenkinsfile (например, из моего отличного сценария запускалась консоль сценариев Jenkins).

Это ошибка / запрос на улучшение плагина заданий Jenkins Pipeline? Или есть какой-либо другой способ, как преобразовать элемент во что-то, откуда у меня будет доступ к желаемой функциональности?


person DelphyM    schedule 03.04.2019    source источник
comment
Во время моей собственной миграции со старых проектов Jenkins на декларативные конвейеры я также перешел с Subversion на git. Поэтому я бы посоветовал вам не думать о переносе вашей системы контроля версий.   -  person PowerStat    schedule 03.04.2019
comment
я бы сказал, что это невозможно, потому что console script работает на сервере, а workflow работает на узлах ... возможно, вам нужно пройти через узлы и каким-то образом запустить там конвейер ...   -  person daggett    schedule 03.04.2019
comment
@PowerStat, да, это была одна из моих первых инициатив и предложений, но она не была одобрена. Это своего рода устаревшие проекты, в основном они обслуживаются и поддерживаются, а Дженкинс работал на своего рода машине разработчика. В любом случае, я все еще хотел бы знать (независимо от фона), как удалить рабочую область задания Pipeline с помощью средств, предоставляемых Jenkins, без непосредственного использования сценария Jenkinsfile (изменяя его либо в SCM, либо в Replay, либо путем изменения задания Jenkins).   -  person DelphyM    schedule 03.04.2019


Ответы (2)


Это не самый красивый способ, но вы можете просто выполнить команду ОС:

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

cmd.execute()

Если вы используете свой код только один раз или не имеете дело с несколькими ОС, вы можете вместо этого сократить код до соответствующей команды:

"rm -rf $workspace".execute()
person Jazzschmidt    schedule 03.04.2019
comment
Интересная идея, и я узнал новый трюк. Однако я изо всех сил пытаюсь использовать его даже с минимальной реализацией с консоли. Имея это: def cmdsh = isUnix() ? "echo LN " : "echo WIN" def cmdbat = isWin ? "echo WIN" : "echo LN" Просто приводит к одному из: * groovy.lang.MissingPropertyException: No such property: isWin for class: Script1 * groovy.lang.MissingMethodException: No signature of method: Script1.isUnix() is applicable for argument types: () ... Не могли бы вы уточнить это немного. - person DelphyM; 03.04.2019
comment
Похоже, вы забыли определить метод isUnix(). В моем примере isWin - это просто переменная, которая ссылается на логическое значение Jenkins.instance.windows, чтобы сделать код более читабельным. - person Jazzschmidt; 04.04.2019
comment
Плохо, ты прав @Jazzschmid. Опять узнал что-то новое (у) - person DelphyM; 05.04.2019

Хорошо, исследуем это еще больше и еще больше ищу в Google и прислушиваюсь к вашим идеям (this один меня особенно вдохновил Дэниел Спилкер). Я добился того, чего хотел, а именно:

Независимо от РАБОЧЕГО ПРОСТРАНСТВА задания конвейера CLEAN-UP через консоль сценариев Jenkins

(только с использованием доступных средств 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

Миссия выполнена:)

использованная литература

В основном Jenkins javadoc

person DelphyM    schedule 04.04.2019