2

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的参数化作业参数,我Invoke Ansible Playbook ”插件的构建步骤中将其用作其库存部分的“内联内容”单选按钮。

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

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

如果Jenkins 中的hosts参数设置为多个主机,即:
app-server1,web-server2
OR
app-server1,app-server1(“,”字符旁边没有任何空格)

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 构建步骤的行为完全相反;在那里,如果我给主机参数“app-server1”的值它可以工作,但给“app-server1”(后缀逗号字符)则不行

4

1 回答 1

1

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

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

在 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 中不起作用。

我使用 $hosts 或类似变量(根据下面的屏幕截图)作为库存(单选按钮)方法的“内联内容” 。

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

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

在此处输入图像描述

于 2016-11-09T04:29:54.340 回答