Ansible: Insert line if not exists

后端 未结 10 1215
庸人自扰
庸人自扰 2020-12-25 11:27

I\'m trying insert a line in a property file using ansible. I want to add some property if it does not exist, but not replace it if such property already exists in the file.

相关标签:
10条回答
  • 2020-12-25 11:32

    Same idea as presented here : https://stackoverflow.com/a/40890850/7231194

    Steps are:

    • Try to replace the line.
    • If replace mod change it, restore
    • If replace mod doesn't change, add the line

    Example

    # Vars
    - name: Set parameters
      set_fact:
        ipAddress    : "127.0.0.1"
        lineSearched : "couchbase.host={{ ipAddress }}"
        lineModified : "couchbase.host={{ ipAddress }} hello"
    
    # Tasks
    - name: Try to replace the line
      replace:
        dest    : /dir/file
        replace : '{{ lineModified }} '
        regexp  : '{{ lineSearched }}$'
        backup  : yes
     register  : checkIfLineIsHere
    
    # If the line not is here, I add it
    - name: Add line
      lineinfile:
      state   : present
      dest    : /dir/file
      line    : '{{ lineSearched }}'
      regexp  : ''
      insertafter: EOF
    when: checkIfLineIsHere.changed == false
    
    # If the line is here, I still want this line in the file, Then restore it
    - name: Restore the searched line.
      lineinfile:
        state   : present
        dest    : /dir/file
        line    : '{{ lineSearched }}'
        regexp  : '{{ lineModified }}$'
      when: checkIfLineIsHere.changed
    
    0 讨论(0)
  • 2020-12-25 11:33

    This is the only way I was able to get this to work.

    - name: checking for host
      shell: cat /database.properties | grep couchbase.host | wc -l
      register: test_grep
    
    - debug: msg="{{test_grep.stdout}}"
    
    - name: adding license server
      lineinfile: dest=/database.properties line="couchbase.host=127.0.0.1"
      when: test_grep.stdout == "0"
    
    0 讨论(0)
  • 2020-12-25 11:38
    - name: add couchbase.host to properties, works like add or replace
      lineinfile:
        path: /database.properties
        regexp: '^couchbase.host=(?!(127.0.0.1))\b'
        line: 'couchbase.host=127.0.0.1'
    

    This code will replace any line ^couchbase.host=* except couchbase.host=127.0.0.1 or will add new line if it does not exist

    0 讨论(0)
  • 2020-12-25 11:40

    Ok, here is mine naive solution... probably not a cross-platform and native Ansible (I've just started to use this tool and still learn it), but definitely shorter:

    - name: Update /path/to/some/file
      shell: grep -q 'regex' /path/to/some/file && echo exists || echo 'text-to-append' >> /path/to/some/file
      register: result
      changed_when: result.stdout.find('exists') == -1
    
    0 讨论(0)
  • 2020-12-25 11:44

    This is possible by simply using lineinfile and check_mode:

    - name: Check if couchbase.host is already defined
      lineinfile:
        state: absent
        path: "/database.properties"
        regexp: "^couchbase.host="
      check_mode: true
      changed_when: false # This just makes things look prettier in the logs
      register: check
    
    - name: Define couchbase.host if undefined
      lineinfile:
        state: present
        path: "/database.properties"
        line: "couchbase.host=127.0.0.1"
      when: check.found == 0
    
    
    0 讨论(0)
  • 2020-12-25 11:47

    The lineinfile module does what it's supposed to: It ensures the line as defined in line is present in the file and the line is identified by your regexp. So no matter what value your setting already has, it will be overridden by your new line.

    If you don't want to override the line you first need to test the content and then apply that condition to the lineinfile module. There is no module for testing the content of a file so you probably need to run grep with a shell command and check the .stdout for content. Something like this (untested):

    - name: Test for line
      shell: grep -c "^couchbase.host" /database.properties || true
      register: test_grep
    

    And then apply the condition to your lineinfile task:

    - name: add couchbase host to properties
      lineinfile:
        dest: /database.properties
        line: couchbase.host=127.0.0.1
      when: test_grep.stdout == "0"
    

    The regexp then can be removed since you already made sure the line doesn't exist so it never would match.

    But maybe you're doing things back to front. Where does that line in the file come from? When you manage your system with Ansible there should be no other mechanisms in place which interfere with the same config files. Maybe you can work around this by adding a default value to your role?

    0 讨论(0)
提交回复
热议问题