【问题标题】:Ansible Do Task If Apt Package Is Missing如果 Apt 包丢失,Ansible 执行任务
【发布时间】:2015-02-26 22:37:57
【问题描述】:

如果缺少特定的 apt 包,我希望执行一系列任务。

例如:

如果未安装石墨碳,请执行以下操作:

- apt: name=debconf-utils state=present
- shell: echo 'graphite-carbon/postrm_remove_databases boolean false' | debconf-set-selections
- apt: name=debconf-utils state=absent

另一个例子:

如果未安装 statsd,请执行以下操作:

- file: path=/tmp/build state=directory
- shell: cd /tmp/build ; git clone https://github.com/etsy/statsd.git ; cd statsd ; dpkg-buildpackage 
- shell: dpkg -i /tmp/build/statsd*.deb

我将如何开始破解这个?

我在想也许我可以做一个-shell: dpkg -l|grep <package name> 并以某种方式捕获返回码。

【问题讨论】:

  • 你不应该过多使用shell 模块。你的剧本不是幂等的。而不是运行 debconf 命令,您应该使用其正确的模块,如下所示docs.ansible.com/debconf_module.html
  • @mxx 谢谢。非常有用的信息。
  • 仅仅切换到使用做同样事情的模块并不能使你的剧本幂等;这两件事是无关的。如果有可用的模块,最好使用模块,但这个理由是错误的。

标签: conditional-statements ansible apt ansible-playbook


【解决方案1】:

您可以使用package_facts 模块(需要 Ansible 2.5):

- name: Gather package facts
  package_facts:
    manager: apt

- name: Install debconf-utils if graphite-carbon is absent
  apt:
    name: debconf-utils
    state: present
  when: '"graphite-carbon" not in ansible_facts.packages'

...

【讨论】:

    【解决方案2】:

    看来我的解决方案正在运行。

    这是我如何工作的一个例子:

    - shell: dpkg-query -W 'statsd'
      ignore_errors: True
      register: is_statd
    
    - name: create build dir
      file: path=/tmp/build state=directory
      when: is_statd|failed
    
    - name: install dev packages for statd build
      apt:  name={{ item }} 
      with_items: 
        - git 
        - devscripts 
        - debhelper
      when: is_statd|failed
    
    - shell: cd /tmp/build ; git clone https://github.com/etsy/statsd.git ; cd statsd ; dpkg-buildpackage 
      when: is_statd|failed
    
    ....
    

    这是另一个例子:

     - name: test if create_superuser.sh exists
      stat: path=/tmp/create_superuser.sh 
      ignore_errors: True
      register: f
    
    - name: create graphite superuser
      command: /tmp/create_superuser.sh
      when: f.stat.exists == True
    

    ...还有一个

    - stat: path=/tmp/build
      ignore_errors: True
      register: build_dir
    
    - name: destroy build dir
      shell: rm -fvR /tmp/build 
      when: build_dir.stat.isdir is defined and build_dir.stat.isdir
    

    【讨论】:

      【解决方案3】:

      我认为您使用dpkg | grep 的方法是正确的,只是返回码无论如何都是0。但是您可以简单地检查输出。

      - shell: dpkg-query -l '<package name>'
        register: dpkg_result
      
      - do_something:
        when: dpkg_result.stdout != ""
      

      【讨论】:

        【解决方案4】:

        我参加这个聚会有点晚了,但这是另一个使用退出代码的示例 - 确保您在 dpkg-query 结果中明确匹配所需的状态文本:

        - name: Check if SystemD is installed
          command: dpkg-query -s systemd | grep 'install ok installed'
          register: dpkg_check
          tags: ntp
        
        - name: Update repositories cache & install SystemD if it is not installed
          apt:
            name: systemd
            update_cache: yes
          when: dpkg_check.rc == 1
          tags: ntp
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-09-07
          • 1970-01-01
          • 2016-07-03
          • 1970-01-01
          • 1970-01-01
          • 2020-04-30
          • 2020-03-07
          相关资源
          最近更新 更多