Ansible - 未指定的标签仍在执行

时间:2017-09-27 17:07:07

标签: ansible

对我的剧本--list-tags运行deploy.yml,我得到以下内容:

  play #1 (localhost): Extract Variable Data From Jenkins Call  TAGS: [main,extract]
      TASK TAGS: [extract, main]

  play #2 (localhost): Pull Repo to Localhost   TAGS: [main,pullRepo]
      TASK TAGS: [main, pullRepo]

  play #3 (gms): Deploy GMS     TAGS: [main,gmsDeploy]
      TASK TAGS: [gmsDeploy, main]

  play #4 (localhost): Execute SQL Scripts      TAGS: [main,sql]
      TASK TAGS: [main, sql]

  play #5 (localhost): Configure Hosts for Copying      TAGS: [main,config,tibco]
      TASK TAGS: [config, main, tibco]

  play #6 (copy_group): Copy Files between servers      TAGS: [main,tibco]
      TASK TAGS: [main, tibco]

  play #7 (localhost): Deploy TIBCO     TAGS: [main,tibco]
      TASK TAGS: [main, tibco]

  play #8 (localhost): Validate Deployment with GMS Heartbeat   TAGS: [validate,main]
      TASK TAGS: [main, validate]

  play #9 (tibco): Clean Up     TAGS: [main,cleanup]
      TASK TAGS: [cleanup, main]

但是,当我在尝试仅执行第二次游戏时运行ansible-playbook deploy.yml --tags "pullRepo"时,它仍会尝试在游戏#4上执行包含任务。我认为包含(包含的行为,而不是包含的任务)是问题,因为游戏#4中的包含之前的任务不会执行。我希望问题是所包含的任务没有被标记。遗憾的是,将sql标记添加到所包含的任务仍会显示尝试执行所包含的任务。

我知道我可以避免使用--skip-tags来运行它们,但我不应该这样做。有什么建议为什么会这样?

我会发布该剧本,但它包含数百行含有专有信息的内容,而我似乎无法使用MCVE复制该问题。

注意:我没有在剧本中使用任何角色,因此由于角色而应用于任务的标签不是一个因素。所有标签都在整个游戏中或游戏中的任务(主要是前者)。

非常接近MCVE:

---

#:PLAY 2 - PULL REPO (LOCALLY)
- name: Pull Repo to Localhost
  hosts: localhost
  any_errors_fatal: true
  tags:
    - pullRepo
    - main
  gather_facts: no
  tasks:

    # Save the repository to the control machine (this machine) for distribution
    - name: Pulling Git Repo for Ansible...
      git: 
        repo: 'https://github.com/ansible/ansible.git'
        dest: '/home/dholt2/ansi'
        accept_hostkey: yes
        force: yes
        recursive: no



# Execute the sql files in the 'Oracle' directory after
## checking if the directory exists
#:PLAY 4 - TEST AND EXECUTE SQL (LOCALLY)
- name: Test & Execute SQL Scripts
  hosts: localhost
  any_errors_fatal: true
  tags:
    - sql
  gather_facts: no
  tasks:

    # Check if the 'Oracle' directory exists. Save the
    ## output to deploy 'Oracle/*' if it does exist.
    - name: Check for presence of the Oracle directory
      stat:
        path: '/home/dholt2/testing/Oracle'
      register: st3


    # Get a list of all sql scripts (using 'ls -v') to run ONLY if the 'Oracle'
    ## directory exists; exclude the rollback script; -v ensures natural ordering of the scripts
    - name: Capture All Scripts To Run
      shell: 'ls -v /home/dholt2/testing/Oracle -I rollback.sql'
      register: f1
      when: st3.stat.isdir is defined

    # Test that the deployment scripts run without error
    - name: Testing SQL Deployment Scripts...
      include: testDeploySql.yml
      any_errors_fatal: true
      loop_control:
        loop_var: deploy_item
      with_items: "{{ f1.stdout_lines }}"
      register: sqlDepl
      when: st3.stat.isdir is defined

执行ansible-playbook deploy2.yml --tags "pullRepo" -vvv的输出:

PLAYBOOK: deploy2.yml *********************************************************************************************************************************************************************************************************************************************************
2 plays in deploy2.yml

PLAY [Pull Repo to Localhost] *************************************************************************************************************************************************************************************************************************************************
META: ran handlers

TASK [Pulling Git Repo for Ansible...] ********************************************************************************************************************************************************************************************************************************************
task path: /home/dholt2/test/deploy2.yml:17
Using module file /usr/lib/python2.6/site-packages/ansible/modules/source_control/git.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: dholt2
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/dholt2/.ansible/tmp/ansible-tmp-1506540242.05-264367109987412 `" && echo ansible-tmp-1506540242.05-264367109987412="` echo /home/dholt2/.ansible/tmp/ansible-tmp-1506540242.05-264367109987412 `" ) && sleep 0'
<127.0.0.1> PUT /tmp/tmpVWukIT TO /home/dholt2/.ansible/tmp/ansible-tmp-1506540242.05-264367109987412/git.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/dholt2/.ansible/tmp/ansible-tmp-1506540242.05-264367109987412/ /home/dholt2/.ansible/tmp/ansible-tmp-1506540242.05-264367109987412/git.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2.6 /home/dholt2/.ansible/tmp/ansible-tmp-1506540242.05-264367109987412/git.py; rm -rf "/home/dholt2/.ansible/tmp/ansible-tmp-1506540242.05-264367109987412/" > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "after": "5c3bbd4620c4a94ece7741ecfe5514a1bd06422b",
    "before": null,
    "changed": true,
    "invocation": {
        "module_args": {
            "accept_hostkey": true,
            "bare": false,
            "clone": true,
            "depth": null,
            "dest": "/home/dholt2/ansi",
            "executable": null,
            "force": true,
            "key_file": null,
            "recursive": false,
            "reference": null,
            "refspec": null,
            "remote": "origin",
            "repo": "https://github.com/ansible/ansible.git",
            "ssh_opts": null,
            "track_submodules": false,
            "umask": null,
            "update": true,
            "verify_commit": false,
            "version": "HEAD"
        }
    }
}
META: ran handlers
META: ran handlers

PLAY [Test & Execute SQL Scripts] *********************************************************************************************************************************************************************************************************************************************
META: ran handlers

TASK [Testing SQL Deployment Scripts...] **************************************************************************************************************************************************************************************************************************************
task path: /home/dholt2/test/deploy2.yml:54
fatal: [localhost]: FAILED! => {
    "failed": true,
    "msg": "'f1' is undefined"
}

NO MORE HOSTS LEFT ************************************************************************************************************************************************************************************************************************************************************

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=1

我为此示例创建了以下目录结构和文件: /home/dholt2/testing/Oracle

在目录内部,我创建了文件a.sqlb.sqlc.sqlrollback.sql

正如它应该的那样,它跳过了第4个搜索Oracle目录的第一个任务,忽略了获取文件列表的以下任务......但是它试图执行包含即使它只应在前一个任务成功的情况下运行。结果是include任务尝试使用的变量不存在 - 所以它抛出一个错误 - 即使它甚至不应该传递when指令,因为第一个任务没有执行到显示该目录存在且上一个任务未获取文件列表。

编辑1于09/28/2017:此任务也在原始剧本中,如果第一个sql脚本失败则回滚:

# Test that the rollback script runs without error
- name: Testing SQL Rollback Script...
  any_errors_fatal: true
  include: testRollbackSql.yml
  register: sqlRoll
  when: st3.stat.isdir is defined

2017年10月16日编辑2:我一直遇到类似的问题。我经常使用with_together,其中一个项目总是填充值,但另一个可能不会(如上面的f1)。因此,使用default()过滤器的下面的答案不起作用,因为总是有一些东西让包含循环幸运的是,我在Ansible的Github上发现了this官方问题。它讨论了为什么会发生这种情况以及如何解决这个问题。

基本上,您仍应使用default()过滤器,但您还需要将static: no添加到任务中。

这支持康斯坦丁关于为什么Ansible可能正在运行标签的声明,即使它们没有被指定。

来自Github问题:

  

...这是静态与动态包含,继承以及在with循环内执行时的问题。

  

问题在于静态包含和何时/有交互Ansible不知道它是否会跳过任务。

1 个答案:

答案 0 :(得分:1)

我明白了..

include不是通常的任务,它是一种陈述,当以静态和动态方式使用时,这种陈述的行为有所不同。
为消除这种歧义,Ansible 2.4中引入了import_tasksinclude_tasks 请参阅有关serverfault的最新问题:https://serverfault.com/questions/875247/whats-the-difference-between-include-tasks-and-import-tasks/875292#875292

当你指定一个标签时,Ansible仍然会完成所有任务,并默默地跳过那些没有相应标签的任务。但是当它遇到动态包含时(就像你的情况一样),它必须处理这个包含语句,因为包含的文件可能包含用该标记标记的任务。

但是你在include语句中有一些未定义的变量,所以它失败了。这是预期的行为。