Jenkins - Passing array/list to Parameterized Remote Build

耗尽温柔 提交于 2019-12-20 06:49:27

问题


I am using Jenkins to remotely run an Ansible playbook via the Publish Over SSH command.

This command:

curl -k -v -X POST https://jenkins.myhost.com/job/Ansible_Deploy/build?token=<appToken> --user <myUser>:<userToken> --data-urlencode json='{"parameter":[{"name":"thisIsAList","value":["one","two","three"]}]}'

should trigger a post-build action to remotely execute the following command over SSH:

ansible-playbook /home/<myUser>/test/practice.yml --extra-vars "thisIsAList=$thisIsAList"

thisIsAList is a string parameter under Job Notifications, and the job is parameterized. I have successfully executed similar commands, but this one fails, assumingly because the value is a list. I have tried both "String Parameter" as well as "Multi-line String Parameter" to no avail.

Here's the stack trace:

org.kohsuke.stapler.WrongTypeException: Got type array but no lister class found for type class java.lang.String
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:723)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:478)
        at org.kohsuke.stapler.RequestImpl.instantiate(RequestImpl.java:777)
Caused: java.lang.IllegalArgumentException: Failed to convert the value parameter of the constructor public hudson.model.StringParameterValue(java.lang.String,java.lang.String)
        at org.kohsuke.stapler.RequestImpl.instantiate(RequestImpl.java:779)
        at org.kohsuke.stapler.RequestImpl.access$200(RequestImpl.java:83)
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:678)
Caused: java.lang.IllegalArgumentException: Failed to instantiate class hudson.model.StringParameterValue from {"name":"thisIsAList","value":["one","two","three"]}
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:680)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:478)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:474)
        at hudson.model.StringParameterDefinition.createValue(StringParameterDefinition.java:88)
        at hudson.model.ParametersDefinitionProperty._doBuild(ParametersDefinitionProperty.java:165)

Note: This may be a duplicate of How to pass an array to a jenkins parameterized job via remote access api? but it hasn't gotten a valid response.


回答1:


Since this level of nesting isn't detailed anywhere in the Jenkins or Ansible documentation I'll shed some light on the topic now that I've solved my issue.

The command:

ansible-playbook /home/<myUsr>/test/practice.yml --extra-vars "thisIsAList=$thisIsAList"

Should have declared thisIsAList to be a dictionary object. I.e.:

ansible-playbook /home/<myUsr>/test/practice.yml --extra-vars "{thisIsAList=$thisIsAList}"

Furthermore, the data in the cURL command should've been formatted differently like so:

json='{"parameter":[{"name":"thisIsAList","value":"[one,two,three]"}]}'

Note: the double-quotes are around the whole list, rather than the individual elements.

Finally, with further nested items (such as dict inside a list) you have to escape the double-quotes like so:

{"parameter":[{"name":"thisIsADictNestedInAList","value":"[{\"name\":\"numbers\",\"value\":[1s, 2s, 3s]}]"}]}

It seems, that at this level of nesting, it is no longer required to double-quote the lists; probably because the quotes one level up already lead it to be interpreted correctly.




回答2:


This is a bit of a guess, based on a similar problem I have seen with a choice parameter. Any documentation I have found seems to be wrong about how to handle these. It shouldn't be a list. Try passing as a string with newlines separating the items.

curl -k -v -X POST https://jenkins.myhost.com/job/Ansible_Deploy/build?token=<appToken> --user <myUser>:<userToken> --data-urlencode json='{"parameter":[{"name":"thisIsAList","value":"one\ntwo\nthree"}]}'

Let me know if this works. I'm interested to find out.


Edit: (based on comments)

Would this work:

curl -k -v -X POST https://jenkins.myhost.com/job/Ansible_Deploy/build?token=<appToken> --user <myUser>:<userToken> --data-urlencode json='{"parameter":[{"name":"thisIsAList","value":"'{\"thisIsAList\": [\"one\",\"two\",\"three\"]}'"}]}'

The nested quotes get a bit ugly. If you are using pipeline or can massage the data in a shell script first, it would probably be cleaner.



来源:https://stackoverflow.com/questions/46310928/jenkins-passing-array-list-to-parameterized-remote-build

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!