failed: Jinja variable 'list object' has no attribute 'iteritems'

9,512 views
Skip to first unread message

schlag

unread,
Feb 28, 2014, 12:06:25 PM2/28/14
to salt-...@googlegroups.com
Hi,

I have a pillar dictionary that I am trying to iterate through with a state, but keep getting the following error:

local:
    Data failed to compile:
----------
    Rendering SLS "base:states.web.django-sites.pip" failed: Jinja variable 'list object' has no attribute 'iteritems'; line 15

---
[...]
{{ pippkg }} pip for django site {{ site }}:
  pip.installed:
    - name:     {{ pippkg }}
      {% if pipargs['require'] is defined %}
    - require:
        {% for type, req in pipargs['require'].iteritems() %}    <======================
      - '{{ type }}':      '{{ req }}'
        {% endfor %}
      {% endif %}
    {% endfor %}
  {% endif %}
[...]
---

The pillar dict looks like this:  http://pastebin.com/2b8tqueL    I've tried removing the dashes for the 'pkg' and 'file' lines, but that just results in conflicting ID errors (eg. Conflicting ID "pkg").

My state looks like this:  http://pastebin.com/pAQ58a4d

I've run it through http://yaml-online-parser.appspot.com/ which comes back with no errors, and seemingly correct, i think.  http://bit.ly/1hvSqWd

Thanks in advance

Colton Myers

unread,
Mar 5, 2014, 6:32:14 PM3/5/14
to salt-...@googlegroups.com
Right, so the problem here is that it's being compiled into a list of dicts.  If you use `salt '*' pillar.items --out=json` you can see it more clearly.  So you can't use iteritems, because it's a list.  You have to iterate over the list, and then for each item in the list (each of which is a dictionary with a single key) you have to pull out the key/value pair and use it.

Does that make sense?

--
Colton Myers


--
You received this message because you are subscribed to the Google Groups "Salt-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to salt-users+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

schlag

unread,
Mar 7, 2014, 1:18:36 PM3/7/14
to salt-...@googlegroups.com
Hm, I think I follow..  I do see what you mean using '--out=json'.   One thing I thought might work was to remove 'iteritems' in favor of iterating through the list and use 'split' to split up the key/value pair, but this gives me a "has no attribute 'split'" error.   Am I even on the right track?

      {%- if 'require' in fileargs %}
    - require:
        {%- for line in fileargs['require'].split() %}
      - {{ line[1] }}:    {{ line[2] }}
        {%- endfor %}
      {%- endif %}


I'll keep digging to try to understand this.  Thank you!

schlag

unread,
Mar 7, 2014, 1:39:17 PM3/7/14
to salt-...@googlegroups.com
even easier, i tossed split and did this, which seemed to work well:

      {%- if 'require' in fileargs %}
    - require:
        {%- for line in fileargs['require'] %}
      - {{ line }}
        {%- endfor %}
      {%- endif %}


thanks again!

Nerses Papoyan

unread,
Apr 17, 2015, 1:29:57 AM4/17/15
to salt-...@googlegroups.com
Make sure you have a space after ":" in your pillar sls, otherwise it will be rendered as a list, instead of a dictionary : 

This is rendered as a list :

users:

  john:1000

  smith:1001

  salt salt # salt '*' pillar.items |grep -A 5 users

    users:

        john:1000 smith:1001

salt salt # 


Now, if you add a space after " : ", you will get a dictionary : 


salt salt # salt '*' pillar.items |grep -A 5 users

    users:

        ----------

        john:

            1000

        smith:

            1001

salt salt #


And your code should work after it's rendered as a dictionary : 

{% for user, uid in pillar.get('users', {}).items() %}

{{user}}:

  user.present:

    - uid: {{uid}}

{% endfor %}


Hope this helps



Reply all
Reply to author
Forward
0 new messages