19

I'm looking to do a series of tasks if a specific apt package is missing.

for example:

if graphite-carbon is NOT installed do:

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

another example:

if statsd is NOT installed do:

- 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

How would I begin to crack this?

I'm thinking maybe I can do a -shell: dpkg -l|grep <package name> and capture the return code somehow.

Simply Seth
  • 3,246
  • 17
  • 51
  • 77
  • You should not use `shell` module so much. Your playbooks are not idempotent. Instead of running debconf command, you should use its proper module as shows here http://docs.ansible.com/debconf_module.html – Mxx Feb 27 '15 at 06:49
  • 3
    Merely switching to using a module that does the same thing does not make your playbook idempotent; the two things are unrelated. It may be a better idea to use a module if one is available, but this rationale is wrong. – Richard E. Silverman Nov 27 '17 at 16:01

4 Answers4

18

You can use the package_facts module (requires 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'

...
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
sduthil
  • 799
  • 6
  • 8
11

It looks like my solution is working.

This is an example of how I have it working:

- 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

....

Here is another example:

 - 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

...and one more

- 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
Simply Seth
  • 3,246
  • 17
  • 51
  • 77
4

I think you're on the right track with the dpkg | grep, only that the return code will be 0 in any case. But you can simply check the output.

- shell: dpkg-query -l '<package name>'
  register: dpkg_result

- do_something:
  when: dpkg_result.stdout != ""
udondan
  • 57,263
  • 20
  • 190
  • 175
2

I'm a bit late to this party but here's another example that uses exit codes - ensure you explicitly match the desired status text in the dpkg-query results:

- 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
dom_hutton
  • 148
  • 1
  • 7