【问题标题】:ansible playbook command line / Jenkins Ansible plugin / parameter NOT accepting space(s) / comma(s) for host valuesansible playbook 命令行 / Jenkins Ansible 插件 / 参数不接受主机值的空格 / 逗号
【发布时间】:2017-03-22 18:40:43
【问题描述】:

Jenkins 版本:2.7.4
Ansible/Playbook 版本:2.1.1.0

Ansible 剧本文件: [ vagrant@/tmp ] $ ls -l pb.yml

-rw-rw-r--. 1 vagrant vagrant 189 Nov  2 05:39 pb.yml

[ 流浪者@/tmp ] $ 猫 $_

---
#- hosts: "{{ host }}"
- hosts: all
  gather_facts: False

#  vars:
#   - host: "all"

  tasks:
    - name: Hello
      shell: "echo hello"
      tags:
         - hello

    - name: Bye
      shell: "echo bye"
      tags:
         - bye

当我在 ansible/host 机器上在命令行上运行以下命令时,如果我只传递一个或多个主机,在 之后有或没有空格,它就可以工作"," 主机值之间的字符:

$ /usr/bin/ansible-playbook tasks/pb.yml -i "app-server1" -f 5 --private-key /tmp/ssh738232337886876255.key -u ubuntu

如果我通过多个主机(cmd 行),它仍然有效(PS:即使我有 , 作为库存主机列表的后缀):

$ /usr/bin/ansible-playbook tasks/pb.yml -i "app-server1,web-server2" -f 5 --private-key /tmp/ssh738232337886876255.key -u ubuntu
$ /usr/bin/ansible-playbook tasks/pb.yml -i "app-server1,web-server2," -f 5 --private-key /tmp/ssh738232337886876255.key -u ubuntu

但是,在 -i 选项的值中传递了一个空格字符,我看到它适用于没有空间的服务器条目,并且对于带有空格后缀/前缀的同一主机(至少根据标准输出控制台上显示的内容)。

例如使用 ansible 命令运行“-m setup”(收集事实),请注意以下输出中的空格字符 proxy-server3 |无法访问! 行。

如果我运行 -m setup(ansible 命令) - 或者 - 即使我运行相同的 playbook(ansible-playbook 命令),我也会看到类似的错误 UNREACHABLE,如下所示:

$ /usr/bin/ansible all -m setup -i "app-server1, proxy-server3," -f 5 --private-key /tmp/ssh738232337886876255.key -u ubuntu

 proxy-server3 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}
app-server1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.124.12.101"
        ],
        ...more...json...stuff..here
        ...

现在,我在 Jenkins 的构建步骤中调用 Ansible Playbook。 在 Jenkins 中,我有一个名为 hosts 的参数化作业参数,我使用 within "Invoke Ansible Playbook" 插件的构建步骤作为 "inline content” 单选按钮,用于其 inventory 部分。

当我只传递“app-server1”并启动作业时,Jenkins 正在成功运行作业并按预期运行 ansible-playbook .yml 文件。

但是,当我提供具有多个逗号分隔值的 hosts 变量时,它会出错。

如果 Jenkins 中的 hosts 参数设置为多个主机,即:
app-server1,web-server2

app-server1,app-server1(“,”字符旁边没有任何空格)
OR
app-server1,web-server2,(PS:这里 , 是值的后缀)。

我收到以下错误:

23:48:00 PLAY [all] *********************************************************************
23:48:00 
23:48:00 TASK [hello] ******************************************************
23:48:01 fatal: [app-server1,web-server2]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh.", "unreachable": true}
23:48:01 
23:48:01 PLAY RECAP *********************************************************************
23:48:01 app-server1,web-server2 : ok=0    changed=0    unreachable=1    failed=0   
23:48:01 
23:48:01 FATAL: command execution failed
23:48:01 hudson.AbortException: Ansible playbook execution failed
23:48:01    at org.jenkinsci.plugins.ansible.AnsiblePlaybookBuilder.perform(AnsiblePlaybookBuilder.java:227)
23:48:01    at org.jenkinsci.plugins.ansible.AnsiblePlaybookBuilder.perform(AnsiblePlaybookBuilder.java:200)
23:48:01    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78)
23:48:01    at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
23:48:01    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:779)
23:48:01    at hudson.model.Build$BuildExecution.build(Build.java:205)
23:48:01    at hudson.model.Build$BuildExecution.doRun(Build.java:162)
23:48:01    at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534)
23:48:01    at hudson.model.Run.execute(Run.java:1741)
23:48:01    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
23:48:01    at hudson.model.ResourceController.execute(ResourceController.java:98)
23:48:01    at hudson.model.Executor.run(Executor.java:410)
23:48:01 ERROR: Ansible playbook execution failed
23:48:01 Finished: FAILURE


(当 hosts 参数值使用 , 作为后缀)


23:48:01 fatal: [app-server1,web-server2,]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh.", "unreachable": true}
23:48:01 
23:48:01 PLAY RECAP *********************************************************************
23:48:01 app-server1,web-server2, : ok=0    changed=0    unreachable=1    failed=0   
23:48:01 
23:48:01 FATAL: command execution failed


如果我在两个主机值之间给出一个空格(不管末尾的后缀 , 字符如何),我会收到不同的错误消息。

示例:我将以下值传递给参数 hosts
app-server1, web-server2

app-server1、web-server2、proxy-server3、

错误示例:

23:49:53 ERROR! /tmp/inventory5444675088910579622.ini:1: Expected key=value host variable assignment, got: app-server1,
23:49:53 FATAL: command execution failed
23:49:53 hudson.AbortException: Ansible playbook execution failed
23:49:53    at org.jenkinsci.plugins.ansible.AnsiblePlaybookBuilder.perform(AnsiblePlaybookBuilder.java:227)
23:49:53    at org.jenkinsci.plugins.ansible.AnsiblePlaybookBuilder.perform(AnsiblePlaybookBuilder.java:200)
23:49:53    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78)
23:49:53    at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
23:49:53    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:779)
23:49:53    at hudson.model.Build$BuildExecution.build(Build.java:205)
23:49:53    at hudson.model.Build$BuildExecution.doRun(Build.java:162)
23:49:53    at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534)
23:49:53    at hudson.model.Run.execute(Run.java:1741)
23:49:53    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
23:49:53    at hudson.model.ResourceController.execute(ResourceController.java:98)
23:49:53    at hudson.model.Executor.run(Executor.java:410)
23:49:53 ERROR: Ansible playbook execution failed

问题:

  1. 当我在 ansible 命令或 ansible-playbook 命令中为 -i 选项的值提供空格时,为什么没有自动删除空格?如果主机在 -i 选项的双引号内用逗号“,”字符周围的空格字符传递,我该如何摆脱这种情况。我知道我可以事先使用 sed-i 选项默认情况下应忽略“,”字符旁边的任何空格(无论是空格是/在逗号旁边加前缀/后缀)。

  2. 在我的 Jenkins 工作中(当我没有在参数的值中留出任何空间时),当值具有“, ",而它在命令行成功?

  3. 提供 -i "app-server1"(在命令行中)不起作用。但是,当我给出 -i "app-server1," 时它会起作用(请参阅引号中的末尾)。
    在 Jenkins 中使用参数(字符串类型)和使用 Invoke Ansible Playbook 构建步骤的行为完全相反;在那里,如果我给 hosts 参数“app-server1”的值它可以工作,但是给 "app-server1," (后缀逗号字符)不会 NOT

【问题讨论】:

    标签: jenkins ansible-playbook ssh-keys ansible-2.x failed-to-connect


    【解决方案1】:

    至少在 Jenkins 中找到了问题和解决方案。

    这似乎是 BUG 或需要 Jenkins 中可用的“Ansible Plugin”中的增强/功能请求可能是我'我对内联一词的含义不正确)但是当为“内联内容”(单选按钮)选择 INVENTORY 方法并且如果我们使用变量($hosts / etc ) 其中包含逗号分隔和/或逗号+空格分隔的主机名/IP 列表等,则 Ansible 无法运行该剧本。

    在 Jenkins JIRA 中打开了针对此插件的请求:https://issues.jenkins-ci.org/browse/JENKINS-39611

    使用“Invoke Ansible Playbook”中的“文件”单选按钮/方法创建库存文件的解决方法实际上在这里有效,但我试图只使用一个普通的“${variable}”,我的假设是,插件应该像我们在命令行中传递 -i 选项一样对待它。

    因此,增强 第三个单选按钮 会有很大帮助。

    例如: 第三个单选按钮(逗号分隔列表/变量),用户只需指定“${myHosts}”并完成它(而不是创建文件并使用文件单选按钮或 使用“内联内容”方法时编写适当的内联库存文件)。

    我的假设是,如果我想将主机信息作为逗号分隔/逗号兼空格分隔列表传递(根据 --help 文档)并在此插件中模仿相同的内容,它应该可以工作,请参阅下面的 --help对于 ansible / ansible-playbook -i 选项。

    我猜对于命令行问题,逗号/空格必须使用 sedtr 类似的命令来解决。

    ansibleansible-playbook 文档说 -i 选项指定要用于 Ansible 的清单(主机信息) ,我们可以将其定义为相对/绝对路径,默认为 /etc/ansible/hosts 或逗号分隔的主机列表

    ansible --help || ansible-playbook --help
    
      -i INVENTORY, --inventory-file=INVENTORY
                            specify inventory host path
                            (default=/etc/ansible/hosts) or comma separated host
                            list.
    

    无论如何,我的问题是围绕 逗号分隔的主机列表,因为它在 Ansible Invoke Playbook 插件的 构建步骤 中的 Jenkins 中不起作用。

    我在 inventory(单选按钮)方法中使用 $hosts 或类似变量(如下面的屏幕截图)作为“inline content”。

    我做了什么来解决:
    我创建了一个临时(又名 mktemp)文件并将包含空格或逗号的一个班轮主机信息列表过滤到此临时文件中,并将此临时文件用作“File”(Radio button) 在“Invoke Ansible Playbook”构建步骤中传递库存信息(关于主机)的方法。

    现在,我在 Jenkins 中没有收到上述错误消息。 Ansible 部分完成后,我将删除这些临时文件(不必这样做,因为它们都位于 /tmp 位置,如果您希望它们位于 Jenkins 工作区位置,那么 mktemp -p 。可用于在当前工作目录中创建临时文件)。

    【讨论】:

    • 感谢您的错误报告和分析。我马上去看看。
    猜你喜欢
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2015-11-17
    • 2020-03-29
    • 2017-09-16
    • 1970-01-01
    • 2020-03-28
    相关资源
    最近更新 更多