问题
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