2

I'm trying to install and configure an application server in a local vagrant vm. For the provisioning Ansible is used. The configuration can be done after the first start is finished. At this time it's listening on localhost:8000. After that I can copy the configuration file and restart the service. After that the port changes to 8081.

The thing is, I need to wait for the first start to be completed, before I override the config file. To check if the first start is done I used the url module in a loop, which works good. So the vm gets provisioned at the first vagrant up --provision.

But, if there's another vagrant provision and the Ansible playbook is doing the url module with the loop it's failing because of the changed port. So I tried this:

- name: configure / check for default server.conf


- command: grep "url.httpport=8081" "/{{ base_dir }}/conf/server.conf"
  ignore_errors: yes
  register: output

- name: configure / Check that app-server is installed successfully (8000)
  block:
    - get_url:
        url: http://localhost:8000/version.txt
        dest: /tmp
      register: result
      until: result is succeeded
      retries: 10
      delay: 30
      register: started
  when: output.rc == 1

- name: configure / Check that app-server is installed successfully (8081)
  block:
    - get_url:
        url: http://localhost:8081/version.txt
        dest: /tmp
      register: result
      until: result is succeeded
      retries: 10
      delay: 30
      register: started
  when: output.rc == 0

My idea is, that regarding to the return code, the correct block is chosen and the other one is skipped. But the result is this:

TASK [glue-tomcat8 : configure / check for default server.conf] ***
fatal: [devaws]: FAILED! => {"changed": true, "cmd": ["grep", ".url.httpport=8081", "/opt5/conf/server.conf"], "delta": "0:00:00.003016", "end": "2018-05-22 07:11:51.382776", "msg": "non-zero return code", "rc": 1, "start": "2018-05-22 07:11:51.379760", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [glue-tomcat8 : Check that app server is installed successfully (8000)] ***
fatal: [devaws]: FAILED! => {"msg": "The conditional check 'result is succeeded' failed. The error was: The failed test expects a dictionary"}

So, it seems, that there's a problem with the conditional check of the get_url module. When used alone, without when conditional (when) and not inside of a block, it's working. My guess is, that Ansible has issues with combining until and when. I can not find anything regarding this in the documentation. So any help is appreciated and thank you in advance.

audioslave
  • 125
  • 1
  • 1
  • 11
  • Don't use a block for a single task. Also, be aware that the error handling for blocks can surprise you. These are single tasks, so a when on each alone should select more as you expected. – Paul Hodges May 22 '18 at 14:18

2 Answers2

4

I got it working. It was a layer 8 (me) issue :) The variable started is a leftover and is not needed. Looks like Ansible was irritated by that variable. Here is my working code:

- command: grep "url.httpport=8081" "/{{ base_dir }}/conf/server.conf"
  ignore_errors: yes
  register: output

- get_url:
    url: http://localhost:8000/version.txt
    dest: /tmp
  register: result
  until: result is succeeded
  retries: 10
  delay: 30
  when: output.rc == 1

- get_url:
    url: http://localhost:8081/version.txt
    dest: /tmp
  register: result
  until: result is succeeded
  retries: 10
  delay: 30
  when: output.rc == 0
audioslave
  • 125
  • 1
  • 1
  • 11
1

First of all, I recommend not using blocks for only one (1) tasks. It doesn't make sense.

Secondly, I recommend checking your ports with wait_for module. So if you want to check port 8000 or 8001 do something like:

---
  - name: Wait_For Example
    hosts: localhost
    gather_facts: False


    tasks:

      - name: Wait for port 443
        wait_for:
          port: 443
          delay: 0
          timeout: 3
          state: started
        register: _port443
        ignore_errors: True


      - name: Wait for port 8001
        wait_for:
          port: 8001
          delay: 0
          timeout: 3
          state: started
        register: _port8001
        ignore_errors: True


      - name: Debug
        debug:
          var: _port443
        when: 
          - _port443.state is defined
          - _port443.state == "started"
          - _port443.port == 443


      - name: Debug
        debug:
          var: _port8001
        when: 
          - _port8001.state is defined
          - _port8001.state == "started"
          - _port8001.port == 443

Be careful, because you are using the same variable started in both cases.

imjoseangel
  • 3,543
  • 3
  • 22
  • 30
  • Thanks for your answer. A check for the opened port is not enough, because the server is opening the port before it is finished before is has extracted and loaded the jar files completely. So it's not a valid check and therefor I need to try to download the version.txt file. The variable started is a leftover of something I tried before and forgot to delete. Sorry for that. – audioslave May 22 '18 at 11:43