Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible : define when a command doesn't have to run (building ruby from source)

Tags:

ruby

ansible

Here is the section of my playbook responsible for downloading and building ruby from source :

  vars:
    ruby_version: '2.0.0-p247'
    ruby_url: 'ftp://ftp.ruby-lang.org//pub/ruby/2.0/ruby-{{ ruby_version }}.tar.gz'

  tasks: 

  - name: Ensure ruby dependencies are installed
    apt: pkg=$item state=installed update-cache=yes
    sudo: yes
    with_items:
      - build-essential
      - git-core
      - libreadline6-dev
      - libyaml-dev
      - libsqlite3-dev
      - sqlite3
      - libgdbm-dev
      - libncurses5-dev
      - libtool
      - bison
      - libffi-dev
      - libdigest-hmac-perl
      - unzip
      - zlib1g
      - zlib1g-dev

  - name: Ensure the ruby source is downloaded
    get_url: url=$ruby_url dest=/home/vagrant/ruby-{{ ruby_version }}.tar

  - name: Ensure the ruby source is extracted
    command: tar -zxf /home/vagrant/ruby-$ruby_version.tar creates=/home/vagrant/ruby-{{ ruby_version }}

  - name: Ensure ruby is installed
    command: $item chdir=/home/vagrant/ruby-$ruby_version
    with_items:
      - ./configure
      - make
      - sudo make install

The last task (configure make and make install) is run at every provisioning.

I can check if ruby is already installed with the correct version with ruby -v. How can I define in my playbook that this is a condition to run this step?

Also, is there a way to make this a condition for the entire task list, and not only the last one ?

like image 810
MrRuru Avatar asked Nov 09 '13 16:11

MrRuru


1 Answers

You can use the register task parameter to save the results of ruby -v into a variable, and then use the when task parameter to conditionally execute tasks.

Your example would then look something like this:

  vars:
    ruby_version: '2.0.0-p247'
    ruby_url: 'ftp://ftp.ruby-lang.org//pub/ruby/2.0/ruby-{{ ruby_version }}.tar.gz'

  tasks:

  - name: get currently installed ruby version
    command: ruby -v
    register: result
    ignore_errors: True

  - name: Ensure ruby dependencies are installed
    apt: pkg={{ item }} state=installed update-cache=yes
    sudo: yes
    with_items:
      - build-essential
      - git-core
      - libreadline6-dev
      - libyaml-dev
      - libsqlite3-dev
      - sqlite3
      - libgdbm-dev
      - libncurses5-dev
      - libtool
      - bison
      - libffi-dev
      - libdigest-hmac-perl
      - unzip
      - zlib1g
      - zlib1g-dev
    when: result.rc !=0 or result.stdout.split()[1] != ruby_version

  - name: Ensure the ruby source is downloaded
    get_url: url={{ ruby_url }} dest=/home/vagrant/ruby-{{ ruby_version }}.tar
    when: result.rc !=0 or result.stdout.split()[1] != ruby_version

  - name: Ensure the ruby source is extracted
    command: tar -zxf /home/vagrant/ruby-{{ ruby_version }}.tar creates=/home/vagrant/ruby-{{ ruby_version }}
    when: result.rc !=0 or result.stdout.split()[1] != ruby_version

  - name: Ensure ruby is installed
    command: $item chdir=/home/vagrant/ruby-{{ ruby_version }}
    with_items:
      - ./configure
      - make
      - sudo make install
    when: result.rc !=0 or result.stdout.split()[1] != ruby_version

You can also move the tasks to a separate file (e.g., install_ruby_from_source.yaml), and then conditionally include the file:

  vars:
    ruby_version: '2.0.0-p247'
    ruby_url: 'ftp://ftp.ruby-lang.org//pub/ruby/2.0/ruby-{{ ruby_version }}.tar.gz'

  tasks:

  - name: get currently installed ruby version
    command: ruby -v
    register: result
    ignore_errors: True

  - include: /path/to/install_ruby_from_source.yaml
    when: result.rc !=0 or result.stdout.split()[1] != ruby_version
like image 101
Lorin Hochstein Avatar answered Oct 23 '22 20:10

Lorin Hochstein