首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何“不多次运行”命令/shell任务在“Ansible剧本”中

如何“不多次运行”命令/shell任务在“Ansible剧本”中
EN

Stack Overflow用户
提问于 2022-01-08 10:03:37
回答 3查看 323关注 0票数 0

我在Ansible中有一项任务是通过RubyGems选项安装SASS实用程序,它运行良好,没有任何问题。如果我再次运行相同的剧本,它将再次尝试重新安装此实用程序。

在本例中,如何在Ansible剧本中使用命令或shell使用的情况下运行一次。我以某种方式处理了它,不是使用'when‘选项来运行安装,而是需要更好的逻辑/实现指导。

任务信息:

代码语言:javascript
复制
- name: Install SASS packages by using npm utility.
  command: /usr/bin/npm install -g sass

为了避免在Ansible剧本中重新运行上面的命令任务,我使用了下面的验证逻辑,并添加了下面提供的'when‘选项。这样做好吗?还是我们有更好的办法处理这个问题?

代码语言:javascript
复制
- name: Validation of SASS packages availability.
  shell: /usr/local/bin/sass --version
  register: result
- debug:
    msg: "{{ result.stdout }}"

- name: Install SASS packages by using npm utility.
  command: /usr/bin/npm install -g sass
  when: "'No such file or directory' in result.stdout"

结果:

代码语言:javascript
复制
TASK [mean-stack : Validation of SASS packages availability.] ************************************************************************************
changed: [linuxosdev003.local.lab]

TASK [mean-stack : debug] ************************************************************************************************************************
ok: [linuxosdev003.local.lab] => {
    "msg": "1.47.0 compiled with dart2js 2.15.1"
}

TASK [mean-stack : Install SASS packages by using npm utility.] **********************************************************************************
skipping: [linuxosdev003.local.lab]

PLAY RECAP ***************************************************************************************************************************************
linuxosdev003.local.lab    : ok=6    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-01-08 13:54:39

如果您想要一本幂等的剧本,您应该尽可能避免使用commandshell。特别是你的例子-删除sass并尝试你的剧本。它应该会失败。要么检查文件是否存在

代码语言:javascript
复制
- name: "Check, if file exists"
  stat:
    path: "/usr/local/bin/sass"
  register: sass_installed

但是--正如已经评论过的--使用ansible模块来安装NPM包,就像您使用系统包(packageyumapt)或Python模块(使用pip)一样。在上一个RedHat版本2.9中,这个模块也可以在module.html下使用,并且应该很容易:

代码语言:javascript
复制
- name: "Install NPM package: sass"
  npm:
    name: "sass"

如果您需要安装超过一个NPM包,您可以对它们进行循环。

代码语言:javascript
复制
- name: "Install NPM packages"
  npm:
    name: "{{ item }}"
  loop:
    - "package1"
    - "package2"
票数 2
EN

Stack Overflow用户

发布于 2022-01-08 14:14:57

正如@β.εηοιτ.βε和@TRW已经提到的那样,使用模块可以消除这种检查的需要。

但是,如果它就像检查路径是否存在一样简单,那么指挥模块本身可以被使用如下:

代码语言:javascript
复制
- name: Install SASS packages by using npm utility.
  command:
    cmd: /usr/bin/npm install -g sass
    creates: /usr/local/bin/sass

这等于您的when条件,即当creates中给定的路径不存在时,命令将运行。

票数 1
EN

Stack Overflow用户

发布于 2022-01-09 10:45:07

因此,如果包管理器可用于任务,我更喜欢使用@β.εηοιτ.βε和@TRW的解决方案,有时可能需要停留在β.εηοιτ.βε模块上。对于这种情况,我使用类似的方法,如在原来的问题。

代码语言:javascript
复制
---
- hosts: test.example.com
  become: no
  gather_facts: no

  tasks:

  - name: Gather installed Java version, if there is any
    shell:
      cmd: java -version 2>&1 | head -1 | cut -d '"' -f 2
    register: result
    check_mode: false
    changed_when: false
    failed_when: result.rc != 0 and result.rc != 127

  - name: Set default version, if there is no
    set_fact:
      result:
        stdout_lines: "0.0.0_000"
    when: "'command not found' in result.stdout"
    check_mode: false

  - name: Report result
    debug:
      msg: "{{ result.stdout_lines }}"
    check_mode: false

根据已安装的版本,将在必要时调用安装程序或更新程序来安装或更新最新版本。

多亏了

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70631304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档