Как удалить сборки с 11 по 1717 в Дженкинс?

51

Из-за неправильной конфигурации у меня более 1700 неудачных сборок в задании Jenkins.

Как я могу эффективно очистить их?

Аарон Дигулла
источник
3
Здесь обсуждается несколько способов удаления сборок с помощью командной строки: stackoverflow.com/questions/13052390/…
ThomasW

Ответы:

75

У вас есть несколько вариантов:

  • Временно установите количество сборок, которые нужно сохранить в конфигурации задания ( Discard Old Builds ), чтобы эти сборки были удалены после завершения следующей сборки. Если следующая сборка 1800, установите для нее последние 85 или около того. Пометьте все старые сборки (т.е. от 1 до 10) как Keep This Build Forever перед началом следующей сборки. Эта опция не удалит некоторые сборки, если у вас есть нижестоящее задание, которое предотвращает удаление вышестоящих сборок (но это не проблема в вашей ситуации, если все они потерпели неудачу, хотя).

  • Используйте консоль сценариев в разделе Управление Jenkins . Если это задание верхнего уровня (не в папке), то сработает следующее:

    Jenkins.instance.getItemByFullName('JobName').builds.findAll { it.number > 10 && it.number < 1717 }.each { it.delete() }

    Конечно, такой подход обычно требует хороших резервных копий. Есть много вещей, которые вы можете сломать, используя консоль скриптов.

  • Удалите папки сборок с диска (по умолчанию $JENKINS_HOME/jobs/JobName/builds/, используя метку времени запуска в качестве имени папки) и перезапустите Jenkins или перезагрузите конфигурацию с диска . Эта опция не позволит плагинам, которые, например, сохраняют историю SVN в порядке, перемещая любые изменения в последующую сборку, чтобы сделать свою работу.

Даниэль Бек
источник
10
Я нашел другое решение: Использованиеjenkins-cli.jar -s ... delete-builds envjs 11-1717
Аарон Дигулла
Сделал Gist, чтобы перечислить все задания с количеством сборок через терминал. Облегчает поиск работы, которая нуждается в уборке. Может также использоваться через cron в качестве отчета по электронной почте.
Ник
@Nick Проверьте плагин Groovy, в частности, тип шага сборки системы Groovy. Для этого не нужно выходить на улицу Дженкинса, просто создайте работу, которая этим занимается. jenkins.model.Jenkins.instance.getAllItems(hudson.model.Job.class).each { println it.fullDisplayName + " has " + it.builds.size() + " builds" } ; returnСортировка, например, по сборкам аналогично тривиальна.
Даниэль Бек
Для многоотраслевых конвейеров вы можете использовать синтаксис JobName/branch
waitinforatrain
17

Просто сделайте вызов API:

curl -X POST http://jenkinUser:jenkinAPIToken@yourJenkinsURl.com/job/theJob/[11-1717]/doDelete

Чтобы получить APIToken: войдите в Jenkins> Конфигурация> Показать API-токен.

hello_harry
источник
Я думаю, что это лучший подход к проблеме. он может быть выполнен удаленно и предоставляет широкий спектр действий через REST
alfredocambera
Лучший ответ, так как вам не нужно искать банку в установленной системе.
Кит Тайлер
Я имел в виду «вам не нужно ничего скачивать»
Кит Тайлер
«Лучший ответ, так как вам не нужно» - если ваш критерий заключается не в загрузке файла <1 м, чем это лучше, спасибо CLI. Если критерию не нужно вводить запутанные URL-адреса с токенами аутентификации, запомните синтаксис curl (предполагая, что он установлен в первую очередь), и вы предпочитаете команды clear и help, и, возможно, у вас уже есть jar, CLI лучше. Если у вас есть только интерфейс we с установленной консолью сценариев, то она лучше. Как обычно, это зависит.
user17265
для удаления держите навсегда сборки, запускайте toggleLogKeepраньше doDelete.
Fancyoung
16

Как правильно сказал Аарон, вы также можете использовать CLI Jenkins для этой цели:

java -jar jenkins-cli.jar -s http://yourserver.com delete-builds <JobName> 11-1717
jaltek
источник
4

Шаблон для запуска скрипта в консоли скриптов Jenkins. Используйте флаг, reallyDeleteчтобы проверить его перед тем, как фактически удалить:

// Jenkins job
def jobName = 'foo'
// Range of builds to delete
def rs = Fingerprint.RangeSet.fromString("11-1717", false);
// Set to true to actually delete. Use false to test the script.
def reallyDelete = false;

// ----------------------------------
def job = Jenkins.instance.getItemByFullName(jobName);
println("Job: ${job.fullName}");

def builds = Jenkins.instance.getItemByFullName(jobName).getBuilds(rs);
println("Found ${builds.size()} builds");
builds.each{ b-> 
  if (reallyDelete) {
    println("Deleting ${b}");
    b.delete();
  } else {
    println("Found match ${b}");
  }
}
Аарон Дигулла
источник
1

Я столкнулся с той же задачей, когда взял на себя сервер Jenkins, на котором имеется чуть более 150 заданий с до 3000 старых сборок, поэтому я написал небольшой скрипт bash, который сохраняет только последние 10 сборок:

#! /bin/bash

initialPath=$(pwd);

find /var/lib/jenkins/ -type d -name builds | while read jobs
 do

    #############################################################
    ## Enter build-directory of current job and get some numbers
    #############################################################
    cd "$jobs" ;
    ls -d [[:digit:]]* &>/dev/null ;
    rc=$? ;
    if [[ $rc -eq 0 ]] ;
     then
        buildName=$(ls -d [[:digit:]]*)  ;
        latestBuild=$(echo $buildName | awk '{print $NF}') ; # highest number
        oldestBuild=$(echo $buildName | awk '{print $1}') ; # lowest number
        amountOfBuilds=$(echo $buildName | wc -w ) ;
        lastBuildToKeep=$(echo "${latestBuild} 9" | awk '{print $1 - $2}') ;

        ############################################################
        ## Skip Folder if it contains less than 10 builds
        ############################################################
        if [ ${amountOfBuilds} -le 10 ] ;
         then
            echo "Skipping $(pwd) --> less than 10 builds";
         else
            ############################################################
            ## Delete all build-directories except the last 10
            ############################################################
            for (( i=$oldestBuild; i<$lastBuildToKeep; i++))
             do
                echo "Deleting $(pwd)/${i} ..."
                rm -r "$i" ;
            done ;
        fi ;
     else
        echo "Skipping $(pwd) --> Zero builds";
    fi ;
done ;

############################################################
## go back to $initialPath
############################################################
cd "$initialPath" ;

После этого настоятельно рекомендуется перезапустить Jenkins, чтобы избежать проблем. Thx @ Аарон Дигулла

Anyesto
источник
Почему вы не использовали скрипт для консоли Jenkins?
Аарон Дигулла
Потому что я больше знаком с Bash. Это единственная причина.
Anyesto
Понял. Пожалуйста, измените ваш вопрос и добавьте, что Jenkins необходимо перезапустить после этого, чтобы избежать проблем.
Аарон Дигулла
0

Я создал небольшой скрипт на Python, который бы служил этой цели. Ниже приводится сценарий:

delete_jenkins_builds.py

from os import listdir, path
import shutil


job_build_fullpath = '/var/lib/jenkins/jobs/My-Jenkins-Project/builds'
print listdir(job_build_fullpath)

for build_dir in listdir(job_build_fullpath):
        if build_dir.isdigit() and int(build_dir) in range(11, 1718):
                build_dir_fullpath = path.join(job_build_fullpath, build_dir)
                print "Deleting: " + build_dir_fullpath
                shutil.rmtree(build_dir_fullpath)
  • job_build_fullpath - путь к каталогу сборки задания

  • range (start_build_no, end_build_no) - range (11, 1718) ищет все сборки, начиная от сборки №. 11 построить нет. 1717. Пожалуйста, установите его соответственно.

  • shutil.rmtree (build_dir_fullpath) - удаляет каждый каталог сборки, находящийся в диапазоне.

Версия Python: 2.7

Шубхам Соин
источник
Не нужно ли вам перезапустить Дженкинс после этого? Что, если Дженкинс хранит информацию об этих папках в базе данных?
Аарон Дигулла
Да @AaronDigulla, для отражения изменений на портале Jenkins потребуется перезапуск сервера Jenkins.
Шубхам Соин