3
votes

I am running ansible and trying to make this task work, it fails with this error:

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AttributeError: 'list' object has no attribute 'startswith' fatal: [test-1]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""} msg: Unexpected failure during module execution.

The code is:

  - name: Register env Type
    shell: facter configured_setup
    register: setup

  - name: foo tasks
    shell: {{some_script}} -t -a {{hosts}} -i {{inventory_hostname}}
    register: test
    when: setup.stdout == "something"

  - name: fetch group_vars
    fetch:
      src:
       - { "{{ item }}", when: setup.stdout == "something" }
      dest: "{{group_vars}}"
      flat: yes
    with_items:
      - "{{ test.stdout_lines[0] }}"
      - "{{ test.stdout_lines[1] }}"

"fetch group_vars" is the task that always fails, any idea how this can work? What I am trying to do is add more source files to fetch from different setvers. So I want to have more lines under "src:", saying - { filename, when setup.stdout =="something else" }

The full error is:

An exception occurred during task execution. The full traceback is: Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/ansible/executor/task_executor.py", line 96, in run item_results = self._run_loop(items) File "/usr/lib/python2.7/site-packages/ansible/executor/task_executor.py", line 252, in _run_loop res = self._execute(variables=task_vars) File "/usr/lib/python2.7/site-packages/ansible/executor/task_executor.py", line 446, in _execute result = self._handler.run(task_vars=variables) File "/usr/lib/python2.7/site-packages/ansible/plugins/action/fetch.py", line 62, in run source = self._remote_expand_user(source) File "/usr/lib/python2.7/site-packages/ansible/plugins/action/init.py", line 460, in _remote_expand_user if not path.startswith('~'): # FIXME: Windows paths may start with "~ instead of just ~ AttributeError: 'list' object has no attribute 'startswith'

fatal: [test-1]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""} msg: Unexpected failure during module execution.

2
When you start experimenting like you did, make sure you are consistent in your indents. Your YAML uses two positions for mappings and four for sequences (that is measured to the beginning of the element), but the sequence you added under src uses three positions. YAML can keep that apart, but it becomes very difficult to manage for yourself if you are not consistent.Anthon

2 Answers

1
votes

So I ended up doing this (which is working):

  - name: fetch group_vars test
    fetch:
      src: "{{ item }}"
      dest: "{{group_vars}}"
      flat: yes
    with_items:
      - "{{ test.stdout_lines[0] }}"
      - "{{ test.stdout_lines[1] }}"
    when: setup.stdout == "something" and {{something_else}} == True

I also noticed that there might be a bug in ansible related to registers. while using the "when" statement, even if the condition is not met, the register statement takes affect:

  - name: test tasks something enabled
    shell: /tmp/{{populate_script}} -u -a {{hosts}} -r
    register: variable
    when: setup.stdout == "test" and something == True

  - name: test tasks something disabled
    shell: /tmp/{{populate_script}} -u -a {{hosts}}
    register: variable
    when: setup.stdout == "test" and something == False

only one of these conditions will be met, in case the first one is met the second condition will override "variable"

0
votes

The ansible documentation clearly states that fetch, fetches a file, not a list of files. Although one can program an application to deal with both a scalar and a sequence loaded from a YAML document, that is not automatic and would almost certainly have been reflected in the documentation.

Since you already have a sequence at a higher level, just extend that.

- name: Register env Type
  shell: facter configured_setup
  register: setup

- name: transparency tasks
  shell: {{some_script}} -t -a {{hosts}} -i {{inventory_hostname}}
  register: test
  when: setup.stdout == "something"

- name: fetch group_vars
  fetch:
    src: { "{{ item }}", when: setup.stdout == "something" }
    dest: "{{group_vars}}"
    flat: yes
  with_items:
    - "{{ test.stdout_lines[0] }}"
    - "{{ test.stdout_lines[1] }}"

- name: fetch group_vars2
  fetch:
    src: { filename, when setup.stdout =="something else" }
    dest: "{{group_vars}}"
    flat: yes
  with_items:
    - "{{ test.stdout_lines[0] }}"
    - "{{ test.stdout_lines[1] }}"

You might be able to reduce the repetitiveness somewhat by using YAML's anchor and merge:

- name: Register env Type
  shell: facter configured_setup
  register: setup

- name: transparency tasks
  shell: {{some_script}} -t -a {{hosts}} -i {{inventory_hostname}}
  register: test
  when: setup.stdout == "something"

- &fetchtask
  name: fetch group_vars
  fetch: &fetchsrc
    src: { "{{ item }}", when: setup.stdout == "something" }
    dest: "{{group_vars}}"
    flat: yes
  with_items:
    - "{{ test.stdout_lines[0] }}"
    - "{{ test.stdout_lines[1] }}"

- <<: *fetchtask
  name: fetch group_vars2
  fetch:
    <<: *fetchsrc
    src: { filename, when setup.stdout =="something else" }

Ansible probably expands the {{...}} before handing the document to the YAML parser, otherwise the value for shell in the "transparency task" would throw an error. But you should probably still quote that like you do with the value for dest