2016-07-07 3 views
5

Я должен читать значения из файла в моем конвейере. Я использую split(), который помещает их в Array. Мне нужно поместить их в Arraylist, поэтому я использую Arrays.asList(). Проблема у меня это я не в состоянии использовать размер() или длину() методы, поэтому не могу сделать цикл, такие какТруба Дженкинса - как перебирать список

for (ii = 0; ii < var.length; ii++) 

или

for (ii = 0; ii < var.size; ii++) 

потому что я получаю ошибку: неклассифицированное поле java.util.Arrays $ ArrayList длина

Поэтому я попытался использовать a для каждого цикла, но когда я предпринимаю какое-либо действие (например, ls comm и, например), в моем блоке finally он только итерации 1 раз. Но если я просто запускаю команду «эхо», она выполняет итерацию для каждого элемента, как это предполагается. Любые советы о том, как изменить мой код, чтобы заставить его выполнять итерацию для каждого элемента в списке при использовании любой команды?

работает правильно ....

node{ 
    wrap([$class: 'ConfigFileBuildWrapper', managedFiles: [[fileId: 'dest_hosts.txt', targetLocation: '', variable: 'DEST_HOST']]]) { 
     HOST = Arrays.asList(readFile(env.DEST_HOST).split("\\r?\\n")) 
     deploy(HOST) 
    } 
} 

@NonCPS 
def deploy(host){ 
    for (String target : host){ 
     try { 
      echo target 
     } 
     finally { 
      echo target 
     } 
    } 
} 

OUTPUT (итерацию для каждого элемента):

[Pipeline] node 
Running on <obfuscated> 
[Pipeline] { 
[Pipeline] wrap 
provisoning config files... 
copy managed file [<obfuscated>] to file:/var/lib/jenkins/<obfuscated> 
[Pipeline] { 
[Pipeline] readFile 
[Pipeline] echo 
www.testhost.com 
[Pipeline] echo 
www.testhost.com 
[Pipeline] echo 
www.testhost2.com 
[Pipeline] echo 
www.testhost2.com 
[Pipeline] } 
Deleting 1 temporary files 
[Pipeline] // wrap 
[Pipeline] } 
[Pipeline] // node 
[Pipeline] End of Pipeline 
Finished: SUCCESS 

Но если я принять некоторые меры, такие как 'Ls -l' это только итерацию 1 раз

node{ 
    wrap([$class: 'ConfigFileBuildWrapper', managedFiles: [[fileId: 'dest_hosts.txt', targetLocation: '', variable: 'DEST_HOST']]]) { 
     HOST = Arrays.asList(readFile(env.DEST_HOST).split("\\r?\\n")) 
     deploy(HOST) 
    } 
} 

@NonCPS 
def deploy(host){ 
    for (String target : host){ 
     try { 
      echo target 
     } 
     finally { 
      sh 'ls -l' 
     } 
    } 
} 

OUTPUT (только итерацию 1 раз):

[Pipeline] node 
Running on <obfuscated> 
[Pipeline] { 
[Pipeline] wrap 
provisoning config files... 
copy managed file [<obfuscated>] to file:/var/lib/jenkins/<obfuscated> 
[Pipeline] { 
[Pipeline] readFile 
[Pipeline] echo 
www.testhost.com 
[Pipeline] sh 
[sandbox%2Fpipeline-test-new1] Running shell script 
+ ls -l 
total 8 
-rw-r--r-- 1 jenkins jenkins 10 Jun 17 16:07 someFile 
[Pipeline] } 
Deleting 1 temporary files 
[Pipeline] // wrap 
[Pipeline] } 
[Pipeline] // node 
[Pipeline] End of Pipeline 
Finished: SUCCESS 

ответ

5

ArrayList (и вообще Lists) не имеют длину или поле размера, они имеют метод size(). Так что используйте, что в течение:

for (ii = 0; ii < var.size(); ii++) 
+0

Спасибо, что работает. Хотя мне все еще любопытно, почему 2-й цикл выше только повторяет один раз, какие-то идеи? – mdo123

+0

Теперь я переживаю нечто подобное. Насколько я могу судить, это связано с вызовом 'sh'. Вы что-то поняли? – pmmaga

+0

@pmmaga не жалко, я об этом не думал. Я просто использовал ответ @ krzyk, но я принял непринятый ответ @ krzyk, потому что я думаю, что часть ответа должна включать объяснение по поведению, описанному выше. В частности, почему каждый цикл работает с «эхом» в блоке finally, но только выполняет итерацию один раз при выполнении команды sh. Я подумал, что, возможно, sh cmd возвращал статус отсутствия нулевого выхода, но для каждого цикла должен продолжаться для каждого элемента, поэтому я не уверен. – mdo123

1

Я не могу сказать вам точно, почему, как я не понял, как найти полезную информацию о Дженкинс, не тратя часы прибегая к помощи, но я могу сказать вам следующее:

На мгновение я подумал, что вы можете сделать это нормально, добавив «эхо-линию» ПОСЛЕ sh 'echo $ line', но это оказалось вызвано тем, что Дженкинс выполнил ПРЕДЫДУЩУЮ версию сценария ...

Я пробовал всевозможные вещи, и никто из них не работал, тогда я нашел это:

Why an each loop in a Jenkinsfile stops at first iteration

Его известная ошибка в трубопроводе Дженкинса!

(известная ошибка является JENKINS-26481, который говорит: «По крайней мере, некоторые укупорочные выполняются только один раз внутри Groovy СУЗ DSL скриптов, управляемых с помощью плагина рабочих процессов»)

2

В соответствии с этой обучающей программы: https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md#serializing-local-variables

...a method marked with the annotation @NonCPS ... will be treated as “native” by the Pipeline engine, and its local variables never saved. However it may not make any calls to Pipeline steps

В вашем случае вызов sh является операцией шага трубопровода, которую вы, по-видимому, не можете выполнить из аннотированного метода @NonCPS.

Что касается поворота массива в List, то, поскольку мы находимся в Groovy land, вы можете просто использовать метод .toList() на массиве.

Смежные вопросы