运行 在 Jenkins 中使用 ant 命令的 Ansible 剧本

Running Ansible playbook with ant commands in Jenkins

我正在制作一个剧本来自动化环境安装。目前我正在测试同事制作的一些脚本,我只想让詹金斯使用 运行 ant 命令来检查脚本结构是否正确。该脚本位于目标机器中,因为我们只是想测试它们,如果脚本不正确,则无需将文件从一台机器复制到另一台机器。

在我的 Jenkins 中,我配置了 jdk 和推荐的 ant 版本,以便在创建参数化 fresstyle 作业后部署请求的环境。我给 运行 的任务是:

---
- name: compile all
  shell: ant all
  args:
    chdir: "{{ env_home }}/Project/scripts"

- name: Create project tables
  shell: ant create-project-tables
  args:
    chdir: "{{ env_home }}/Project/scripts"

这是第一个包含至少一个 运行 目标上的 ant 命令的角色。何曾詹金斯总是 returns

TASK [build_all : compile all] *****************************************
task path: /opt/testes/env-deployment/roles/build_all/tasks/main.yml:2
[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{ buildPrepaidAll }}
fatal: [srv1]: FAILED! => {"changed": true, "cmd": "ant all", "delta": "0:00:00.003675", "end": "2018-11-07 15:55:15.917745", "msg": "non-zero return code", "rc": 127, "start": "2018-11-07 15:55:15.914070", "stderr": "/bin/sh: ant: command not found", "stderr_lines": ["/bin/sh: ant: command not found"], "stdout": "", "stdout_lines": []}

Jenkins 没有抱怨其他任何事情,只是找不到 ant 命令,如果我在同一文件夹中键入 ant all 命令 运行s

谢天谢地,我找到了问题所在。在我的目标机器上,我安装了 ant 并创建了 ANT_HOME 并将 ANT_HOME/bin 添加到 PATH。

但是因为这是在 bash_profile 上声明的,所以 jenkins 无法识别该命令,因为它没有生成 bash 配置文件的来源,所以我在 ant 命令之前添加了 source {{ ansible_env.HOME }}/.bash_profile && 所以jenkins 用户可以获取 运行 命令

所需的环境变量

TL;DR

使用 Ant 插件 或确保 ant 可执行文件在 ansible 运行时 $PATH 中可用。

Ant Plugin解决方案

在作业配置中添加 Invoke Ant 作为 构建步骤Jenkins Ant 插件):

注意:这个例子是master上的运行。 ant 可执行文件是在 全局工具配置 中定义的。 ant 未在 jenkins 用户 $PATH 中设置,jenkins 使用为作业配置的 ant 可执行文件。

如果 Jenkins 配置为在远程节点上构建,并且如果 ant 安装在 Jenkins 全局工具配置 中定义的同一位置不可用,您需要在节点配置的 Node Properties > Tool Locations 中覆盖 ant 可执行文件位置 ...

Ansible 解决方案

要了解此解决方案,您需要了解错误。参考您的(已编辑)评论:

But ant is there. If I run ant in my target machine ant would give a error because there was no build.xml on the folder, but would work nontheless. And ant env variable is set and also available in PATH. But you gave me an idea. /if the target machine has all set including ant, env var and PATH, then might be the source of the bash_profile. ...

Ansible 连接是非交互式的,您可以在将 -vvvv 与您的 ansible 命令一起使用时在调试跟踪中看到这一点,一个经过编辑的示例:

<172.28.128.13> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/home/bmassey/.ansible/cp/881b67b3d5 172.28.128.13 '/bin/sh -c '...'

.bash_profile 命令在非交互式登录期间不执行。来自 man bash:

An interactive shell is one started without non-option arguments (unless -s is specified) and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.  PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
...
When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

您需要确保 ant 可执行文件在 ansible 可执行文件 $PATH 中可用,您如何执行此操作无关紧要,即编辑 profile 从命令在非交互式 shell 登录或使用 ansible (https://docs.ansible.com/ansible/devel/user_guide/playbooks_environment.html)

设置环境期间执行
- hosts: localhost
  environment:
    PATH: '/opt/ant/apache-ant-1.10.5/bin:{{ ansible_env.PATH }}'

ansible 可执行文件 $PATH 中没有 ant

使用 ansible 可执行文件 $PATH 中的 ant 使用 ansibleenvironment 关键字设置:

---

- hosts: localhost
  environment:
  - PATH: '/opt/ant/apache-ant-1.10.5/bin:{{ ansible_env.PATH }}'
  tasks:
  - name: execute ant build
    local_action:
      module: shell
      args: ant
      chdir: "{{ ansible_env.HOME }}/workspace/example"
    register: ant_build

  - debug: var=ant_build.stdout_lines

略微修改了 ansible-playbook 通过 Jenkins 执行 antansible 可执行文件 $PATH 中使用 ansibleenvironment 关键字设置:

---

- hosts: localhost
  environment:
  - PATH: '/opt/ant/apache-ant-1.10.5/bin:{{ ansible_env.PATH }}'
  tasks:
  - name: execute ant build
    local_action:
      module: shell
      args: ant
      chdir: "{{ lookup('env', 'WORKSPACE') }}"
    register: ant_build
    ...