В конвейере Jenkins мы хотим создать файл конфигурации с переменным содержимым, поэтому мы используем StreamingTemplateEngine.
Теперь нам нужно создать файл конфигурации с необязательными строками в зависимости от карты переменных. Этот пример был нашей первой попыткой (во время разработки / тестирования, сначала написанной простым шрифтом):
import groovy.text.StreamingTemplateEngine
def vars=[
"KEY2": "VAL2",
]
templateText='''
FIXKEY=FIXVAL
<%
if(KEY1) out.print "KEY1="+KEY1+"\\n";
if(KEY2) out.print "KEY2="+KEY2+"\\n";
%>
'''
def engine = new StreamingTemplateEngine()
def template=engine.createTemplate(templateText)
configContent = template.make(vars).toString()
println "CONTENT FROM TEMPLATE IS:"
println configContent;
Так как «KEY1» не существует на карте, мы хотели, чтобы результирующая строка конфигурации была:
FIXKEY=FIXVAL
KEY2=VAL2
Но мы получили это исключение:
Exception in thread "main" groovy.text.TemplateExecutionException: Template execution error at line 4:
3: <%
--> 4: if(KEY1) out.print "KEY1="+KEY1+"\n";
5: if(KEY2) out.print "KEY2="+KEY2+"\n";
at main.run(main.groovy:34)
at main.main(main.groovy)
Caused by: groovy.lang.MissingPropertyException: No such property: KEY1 for class: groovy.tmp.templates.StreamingTemplateScript1
Итак, мы узнали, что каждая переменная, используемая в шаблоне, должна быть определена на карте, как работает этот код:
import groovy.text.StreamingTemplateEngine
def vars=[
"KEY1": "VAL1",
"KEY2": "VAL2",
]
templateText='''
FIXKEY=FIXVAL
<%
if(KEY1) out.print "KEY1="+KEY1+"\\n";
if(KEY2) out.print "KEY2="+KEY2+"\\n";
%>
'''
def engine = new StreamingTemplateEngine()
def template=engine.createTemplate(templateText)
configContent = template.make(vars).toString()
println "CONTENT FROM TEMPLATE IS:"
println configContent;
Но в результате:
FIXKEY=FIXVAL
KEY1=VAL1
KEY2=VAL2
Теперь мы можем определить «KEY2»: false на карте, но с огромным количеством переменных это будет гораздо больше, чем просто определить необходимые переменные и полностью исключить ненужные переменные.
После небольшого поиска мы нашли это:
Исключение StreamingTemplateEngine MissingPropertyException
Мы попробовали второе решение, упомянутое в этой теме:
import groovy.text.StreamingTemplateEngine
def vars=[
"KEY2": "VAL2",
].withDefault { false }
templateText='''
FIXKEY=FIXVAL
<%
if(KEY1) out.print "KEY1="+KEY1+"\\n";
if(KEY2) out.print "KEY2="+KEY2+"\\n";
%>
'''
def engine = new StreamingTemplateEngine()
def template=engine.createTemplate(templateText)
configContent = template.make(vars).toString()
println "CONTENT FROM TEMPLATE IS:"
println configContent;
И это работает, как и ожидалось, в результате содержимое конфигурации:
FIXKEY=FIXVAL
KEY2=VAL2
Отлично, подумали мы, поэтому теперь мы хотим использовать этот фрагмент в конвейере Jenkins, но Jenkins ведет себя как-то иначе, используя этот код этапа тестирования:
import groovy.text.StreamingTemplateEngine
[...]
stage('test') {
def vars=[
"KEY2": "VAL2",
].withDefault { false }
templateText='''
FIXKEY=FIXVAL
<%
if(KEY1) out.print "KEY1="+KEY1+"\\n";
if(KEY2) out.print "KEY2="+KEY2+"\\n";
%>
'''
def engine = new StreamingTemplateEngine()
def template=engine.createTemplate(templateText)
configContent = template.make(vars).toString()
println "CONTENT FROM TEMPLATE IS:"
println configContent;
}
Но результат в Дженкинсе таков:
[Pipeline] {
[Pipeline] stage
[Pipeline] { (test)
[Pipeline] echo
15:07:10 CONTENT FROM TEMPLATE IS:
[Pipeline] echo
15:07:10 false
[Pipeline] }
Обратите внимание на один "ложный" ?? !!
Когда «заполняешь» карту следующим образом:
import groovy.text.StreamingTemplateEngine
[...]
stage('test') {
def vars=[
"KEY1": "VAL1",
"KEY2": "VAL2",
].withDefault { false }
templateText='''
FIXKEY=FIXVAL
<%
if(KEY1) out.print "KEY1="+KEY1+"\\n";
if(KEY2) out.print "KEY2="+KEY2+"\\n";
%>
'''
def engine = new StreamingTemplateEngine()
def template=engine.createTemplate(templateText)
configContent = template.make(vars).toString()
println "CONTENT FROM TEMPLATE IS:"
println configContent;
}
Строка содержимого соответствует ожидаемой:
[Pipeline] stage
[Pipeline] { (test)
[Pipeline] echo
15:09:06 CONTENT FROM TEMPLATE IS:
[Pipeline] echo
15:09:06
15:09:06 FIXKEY=FIXVAL
15:09:06 KEY1=VAL1
15:09:06 KEY2=VAL2
15:09:06
15:09:06
[Pipeline] }
Так почему же Jenkins Pipeline Groovy ведет себя по-разному с тем же фрагментом кода, что и "Простой" Groovy?
Или существует даже совершенно другой подход для решения запроса "переменные линии, основанные на существовании на карте var"?
Спасибо за любую подсказку!
T0mcat