0

Use case: adding bash-completion to dev-environment playbook.

In OSX, I need to write to either .profile or .bash_profile via Ansible. I need to add some config lines to one of those files and would like to do so to whichever one exists. I need to add those lines to the first of those files that exists since OSX looks for .bash_profile, .bash_login, then .profile and stops looking when it finds one of them.

Is there an environment variable I can use to determine which file was used to load the bash config?

Is there a way to create a variable in Ansible that tells Ansible which of those files to write to, depending on the first one in the list (.bash_profile, .bash_login, .profile) that exists?

I've tried this in my existing playbook.yml, which does not overwrite my initially stated var of "bash_config":

    - hosts: localhost
      connection: local
      vars:
        bash_config: "{{ ansible_user_dir }}/.profile"

      tasks:
        - stat: path="{{ ansible_user_dir }}/.profile"
          register: bash_config
          when: bash_config.exists = true
        - stat: path="{{ ansible_user_dir }}/.bash_login"
          register: bash_config
          when: bash_config.exists = true
        - stat: path="{{ ansible_user_dir }}/.bash_profile"
          register: bash_config
          when: bash_config.exists = true
Community
  • 1
  • 1
Eric Poe
  • 383
  • 2
  • 9

2 Answers2

1

You almost had it. Here are a few changes that should get it working.

(I am running ansible version 2.0.0.1).

When in doubt, you should always try to use the debug module. Also when you tried to initialize the variable bash_config, you are initializing it as a string. Where as the stat module returns a dictionary. Documentation for the stat module http://docs.ansible.com/ansible/stat_module.html

- hosts: localhost
  connection: local

  tasks:
  - stat: path="{{ ansible_user_dir }}/.profile"
    register: profile_config
  - debug: var=profile_config

  - stat: path="{{ ansible_user_dir }}/.bash_login"
    register: profile_config
    when: profile_config.stat['exists'] != true
  - debug: var=profile_config

  - stat: path="{{ ansible_user_dir }}/.bash_profile"
    register: profile_config
    when: profile_config.stat['exists'] != true
  - debug: var=profile_config
linuxdynasty
  • 376
  • 2
  • 5
  • That looks like what I was going for. However `profile_config` is not getting registered globally to be referenced in other files. Using Galaxy and Ansible 2.0.1.0. Any ideas? – Eric Poe Mar 17 '16 at 14:59
1

You can use with_first_found for this.

- blockinfile:
    dest: "{{ item }}"
    block: |
      if [ -f `brew --prefix`/etc/bash_completion ]; then
        . `brew --prefix`/etc/bash_completion
      fi
  with_first_found:
    - files:
        - .bash_profile
        - .bash_login
        - .profile
      paths:
        - "{{ ansible_user_dir }}/"

That's not tested, it's just an idea how to archive your goal with the blockinfile module. If you don't use Ansible 2, you need to download blockinfile from Galaxy first.

Please note, this only works because you're playing on localhost. On remote hosts this wouldn't work as with_first_found is checking local files on the Ansible control host.

udondan
  • 57,263
  • 20
  • 190
  • 175
  • I like it! I was doing several things with blockinfile, so this looks like it should work perfectly. Yet, I get an error: fatal: [localhost]: FAILED! => {"failed": true, "msg": "'item' is undefined"} Ansible: 2.0.1.0 – Eric Poe Mar 17 '16 at 14:48
  • - name: Add bash-completion to bash blockinfile: marker: "# {mark} ANSIBLE MANAGED BLOCK - BASH_COMPLETION" dest: "{{ item }}" block: | if [ -f "$(brew --prefix)/etc/bash_completion" ]; then . "$(brew --prefix)/etc/bash_completion" fi with_first_found: - files: - .bash_profile - .bash_login - .profile paths: - "{{ ansible_user_dir }}/" – Eric Poe Mar 17 '16 at 14:50
  • Sorry about the non-codelike block above. Indenting each line 4 spaces did not fix. :( – Eric Poe Mar 17 '16 at 14:56
  • No worries about the format. You can't have formatted code blocks in comments. But I can reproduce the problem. That's really strange. I'll try to figure out what the issue is. – udondan Mar 17 '16 at 14:58
  • Got it. In my answer I had the indention wrong on the module parameters. I guess you fixed it and also added indention to the `with_first_found` section. I updated my answer with correct indention. Please try that, it works for me. – udondan Mar 17 '16 at 15:01