ansible AttributeError: 'list' object has no attribute 'startswith'

18,480

Solution 1

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"

Solution 2

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

Share:
18,480
liad9122
Author by

liad9122

Updated on June 07, 2022

Comments

  • liad9122
    liad9122 almost 2 years

    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.