Jenkins Groovy Modify Params Map: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
Строка 10: Строка 10:
 
У дженкинса есть переменная params которая представляет <BR>
 
У дженкинса есть переменная params которая представляет <BR>
 
мапу параметров которые переданы на вход билду и которые не модифицируемым простым способом
 
мапу параметров которые переданы на вход билду и которые не модифицируемым простым способом
  +
<PRE>
  +
println(params.getClass().getName()
  +
</PRE>
  +
<PRE>
  +
java.util.Collections$UnmodifiableMap
  +
</PRE>
 
<BR>
 
<BR>
 
Доступ к ним можно получить по именами параметров
 
Доступ к ним можно получить по именами параметров
Строка 19: Строка 25:
 
</PRE>
 
</PRE>
   
Такая организация приносит 2 проблемы
+
Такая организация параметров приносит 2 проблемы
 
# Если есть сторонний код который требует наличие параметров и подключается из библиотеки и который нельзя по какой-то причине модифицировать
 
# Если есть сторонний код который требует наличие параметров и подключается из библиотеки и который нельзя по какой-то причине модифицировать
 
# Параметры попадают в переменные окружения всего исполняемого кода
 
# Параметры попадают в переменные окружения всего исполняемого кода
  +
Другими словами - параметры доступны в коде везде и всегда
  +
<PRE>
  +
sh "env"
  +
</PRE>
  +
<PRE>
  +
JENKINS_HOME=/var/lib/jenkins
  +
...
  +
JOB_BASE_NAME=build-frontend-application
  +
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
  +
PARAMETER_1=MY_APP
  +
</PRE>
   
  +
=Зачем использовать параметры большого размера?=
В первом случае требуется модифицировать
 
  +
  +
deploymentConfiguration = readJSON text: params.DEPLOYMENT_CONFIGURATION
  +
  +
Проблема преобретает остроту когда параметр оказывается большим - например тектовое поле в несколько килобайт, и в этом случае ломается практичесуи все - любой вызов конструкции
  +
  +
sh " ... "
  +
завершается с ошибкой
  +
  +
Caused by: java.io.IOException: Cannot run program "/usr/bin/git" (in directory): error=7, Argument list too long
  +
  +
Если для исполнения простых скриптов можно придумать
  +
<PRE>
  +
withEnv(['LARGE_SIZE_PARAMETER=']) {
  +
sh "env"
  +
}
  +
  +
То для конструкций ниже например scm решение не работает.
  +
При этом плагин не стесняется вызывать под-капотом бинарник гита (и нахуя тогда нужен такой плагин? Вопрос открыт но имеем то что имеем)
  +
<PRE>
  +
withEnv(['LARGE_SIZE_PARAMETER=']) {
  +
dir(applicationName) {
  +
checkout scm: [
  +
$class:'GitSCM',
  +
branches : [[name: branch]],
  +
userRemoteConfigs: [[url: gitUrl, credentialsId: gitCredentialsId]]
  +
]
  +
}
  +
}
  +
</PRE>
  +
  +
  +
=Решение=
  +
<PRE>
  +
@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);
  +
}
  +
</PRE>

Версия 12:05, 28 апреля 2022


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

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

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

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


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

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

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

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

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

sh "env"
JENKINS_HOME=/var/lib/jenkins
...
JOB_BASE_NAME=build-frontend-application
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
PARAMETER_1=MY_APP

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

                               deploymentConfiguration = readJSON text: params.DEPLOYMENT_CONFIGURATION

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

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 решение не работает. 
При этом плагин не стесняется вызывать под-капотом бинарник гита (и нахуя тогда нужен такой плагин? Вопрос открыт но имеем то что имеем)
<PRE>
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);
}