Jenkins Groovy Modify Params Map

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


Частный случай - требуется модифицировать params

Суть проблемы

У дженкинса есть переменная params которая представляет
мапу параметров которые переданы на вход билду и которые не модифицируемым простым способом

println(params.getClass().getName()
java.util.Collections$UnmodifiableMap


Доступ к ним можно получить по именами параметров

params.PARAMETER_1
params.PARAMETER_2
...
params.PARAMETER_N

Такая организация параметров приносит 2 проблемы

  1. Если есть сторонний код который требует наличие параметров и подключается из библиотеки и который нельзя по какой-то причине модифицировать
  2. Параметры попадают в переменные окружения всего исполняемого кода что накладывает ограничение на размер параметров

Другими словами - параметры доступны в коде везде и всегда

sh "env"
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
...
PARAMETER_1=MY_APP
...

Зачем использовать параметры большого размера?

  • Это удобно - можно не иметь в описании кучу параметров а иметь один, и через него передавать все что нужно
myJobConfiguration = readJSON text: params.SUPER_LARGE_PARAMETER_FOR_JOB_CONFIGURATION

Размер памяти отведенный под переменные окружения ограничен

  • не помню точное значение для Linux но оно достаточно маленькое что бы в него можно было упереться


Проблема преобретает остроту когда параметр оказывается большим - например тектовое поле в несколько килобайт,
и в этом случае ломается практически все
любой вызов конструкции

sh " ... "

завершается с ошибкой

Caused by: java.io.IOException: Cannot run program "/usr/bin/git" (in directory): error=7, Argument list too long

Если для исполнения простых скриптов можно придумать

withEnv(['LARGE_SIZE_PARAMETER=']) {
 sh "env"
}

То для конструкций ниже например scm решение не работает. При этом плагин не стесняется вызывать под-капотом бинарник гита (и нахуя тогда нужен такой плагин? Вопрос открыт но имеем то что имеем)

withEnv(['LARGE_SIZE_PARAMETER=']) {
  dir(applicationName) {
    checkout scm: [
      $class:'GitSCM',
      branches         : [[name: branch]],
      userRemoteConfigs: [[url: gitUrl, credentialsId: gitCredentialsId]]
    ]
  }
}

Решение

Код найден на прострах интернета и он позволяет модифицировать параметры

@NonCPS
def addOrReplaceParamValue(name, value) {
    def build = currentBuild.getRawBuild();
    def npl = new ArrayList<StringParameterValue>()
    def pv = new hudson.model.StringParameterValue(name,value);
    npl.add(pv);
    def newPa = null
    def oldPa = build.getAction(hudson.model.ParametersAction.class)
    if (oldPa != null) {
        build.actions.remove(oldPa)
        newPa = oldPa.createUpdated(npl)
    } else {
        newPa = new hudson.model.ParametersAction(npl)
    }

    return build.actions.add(newPa);
}
addOrReplaceParamValue("LARGE_SIZE_PARAMETER", "no-data")

У этого решения есть интереснейший side-effect , при попытке вызвать Rebuild в параметре LARGE_SIZE_PARAMETER окажется не то что было изначально, а "no-data"
Тип параметра может отличаться:
def pv = new hudson.model.StringParameterValue(name,value);
def pv = new hudson.model.TextParameterValue(name,value);