Jenkins Groovy Modify Params Map: различия между версиями
Sirmax (обсуждение | вклад) (Новая страница: «Частный случай - требуется модифицировать params») |
Sirmax (обсуждение | вклад) |
||
| (не показано 14 промежуточных версий этого же участника) | |||
| Строка 1: | Строка 1: | ||
| + | [[Категория:Jenkins]] |
||
| + | [[Категория:CICD]] |
||
| + | [[Категория:Groovy]] |
||
| + | [[Категория:GroovyDSL]] |
||
| + | |||
| + | |||
Частный случай - требуется модифицировать params |
Частный случай - требуется модифицировать params |
||
| + | =Суть проблемы= |
||
| + | |||
| + | У дженкинса есть переменная '''params''' которая представляет <BR> |
||
| + | мапу параметров которые переданы на вход билду и которые не модифицируемым простым способом |
||
| + | <PRE> |
||
| + | println(params.getClass().getName() |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | java.util.Collections$UnmodifiableMap |
||
| + | </PRE> |
||
| + | <BR> |
||
| + | Доступ к ним можно получить по именами параметров |
||
| + | <PRE> |
||
| + | params.PARAMETER_1 |
||
| + | params.PARAMETER_2 |
||
| + | ... |
||
| + | params.PARAMETER_N |
||
| + | </PRE> |
||
| + | |||
| + | Такая организация параметров приносит 2 проблемы |
||
| + | # Если есть сторонний код который требует наличие параметров и подключается из библиотеки и который нельзя по какой-то причине модифицировать |
||
| + | # Параметры попадают в переменные окружения всего исполняемого кода что накладывает ограничение на размер параметров |
||
| + | Другими словами - параметры доступны в коде везде и всегда |
||
| + | <PRE> |
||
| + | sh "env" |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | 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> |
||
| + | |||
| + | =Зачем использовать параметры большого размера?= |
||
| + | * Это удобно - можно не иметь в описании кучу параметров а иметь один, и через него передавать все что нужно |
||
| + | <PRE> |
||
| + | myJobConfiguration = readJSON text: params.SUPER_LARGE_PARAMETER_FOR_JOB_CONFIGURATION |
||
| + | </PRE> |
||
| + | |||
| + | =Размер памяти отведенный под переменные окружения ограничен= |
||
| + | * не помню точное значение для Linux но оно достаточно маленькое что бы в него можно было упереться |
||
| + | <BR> |
||
| + | Проблема преобретает остроту когда параметр оказывается большим - например тектовое поле в несколько килобайт, |
||
| + | <BR> |
||
| + | и в этом случае ломается практически все |
||
| + | <BR> |
||
| + | любой вызов конструкции |
||
| + | <PRE> |
||
| + | sh " ... " |
||
| + | </PRE> |
||
| + | завершается с ошибкой |
||
| + | <PRE> |
||
| + | Caused by: java.io.IOException: Cannot run program "/usr/bin/git" (in directory): error=7, Argument list too long |
||
| + | </PRE> |
||
| + | Если для исполнения простых скриптов можно придумать |
||
| + | <PRE> |
||
| + | withEnv(['LARGE_SIZE_PARAMETER=']) { |
||
| + | sh "env" |
||
| + | } |
||
| + | </PRE> |
||
| + | То для конструкций ниже например 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> |
||
| + | |||
| + | <PRE> |
||
| + | addOrReplaceParamValue("LARGE_SIZE_PARAMETER", "no-data") |
||
| + | </PRE> |
||
| + | |||
| + | У этого решения есть интереснейший side-effect , при попытке вызвать Rebuild в параметре '''LARGE_SIZE_PARAMETER''' окажется не то что было изначально, а '''"no-data"''' |
||
| + | <BR> |
||
| + | Тип параметра может отличаться: <BR> |
||
| + | ''' def pv = new hudson.model.StringParameterValue(name,value);'''<BR> |
||
| + | ''' def pv = new hudson.model.TextParameterValue(name,value);''' |
||
Текущая версия на 10:38, 29 апреля 2022
Частный случай - требуется модифицировать params
Суть проблемы
У дженкинса есть переменная params которая представляет
мапу параметров которые переданы на вход билду и которые не модифицируемым простым способом
println(params.getClass().getName()
java.util.Collections$UnmodifiableMap
Доступ к ним можно получить по именами параметров
params.PARAMETER_1 params.PARAMETER_2 ... params.PARAMETER_N
Такая организация параметров приносит 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);