Jinja Debugging?

739 views
Skip to first unread message

Kit Plummer

unread,
Jun 30, 2015, 10:13:45 AM6/30/15
to salt-...@googlegroups.com
Hey Peeps.

I'm at wits-end with trying to figure out an issue I have with Jinja inside some Pillar configuration.

Here's the output error:

[CRITICAL] Rendering SLS 'base:accumulo' failed: Jinja variable No first item, sequence was empty.
local:
    - Rendering SLS 'base:accumulo' failed: Jinja variable No first item, sequence was empty.

And here's the code that I believe is cause this error - at least it is the only place that is using 'first()'.

{% if (salt['mine.get']('roles:accumulo_master', 'network.interfaces', 'grain').keys()|first() is none) %}
{%- set accumulo_master = salt['mine.get']('roles:accumulo_master', 'network.interfaces', 'grain').keys()|first() %}
{%- endif %}
{%- set accumulo_master = gc.get('accumulo_master', pc.get('accumulo_master', 'localhost' )) %}

I've tried a handful of different ways to get this to work, none successful.  The 'first()' always seems to fail.  The reason I'm trying to handle the 'mine.get' is because I want to be able to support this formula in a 'masterless' environment, where different nodes are all the same machine.  I'm stuck and am too naive about Salt to figure out what to do or try next.  Any help would be greatly appreciated.

TIA.
Kit

Nicholas Capo

unread,
Jun 30, 2015, 10:32:49 AM6/30/15
to salt-...@googlegroups.com

Is this psudo code version correct?

If grain.first() is none:
  Set x = grain.first()

I think it might be the second call to first() that's failing since the dict is empty.

If it helps:

Jinja is /almost/ python (at least close enough). In python an empty list or empty dict is falsey ([] == False == {}).

So I think you can just do:

{% if not (salt['mine.get']('roles:accumulo_master', 'network.interfaces', 'grain') %}

To test for an empty dict.

But I'm not sure that's what you wanted.

Nicholas


--
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/d/optout.

David Maze

unread,
Jun 30, 2015, 10:36:55 AM6/30/15
to salt-...@googlegroups.com
On Tuesday, June 30, 2015 at 10:13:45 AM UTC-4, Kit Plummer wrote:
I'm at wits-end with trying to figure out an issue I have with Jinja inside some Pillar configuration.

For accumulo-formula specifically...have you correctly set up the mine?  Either the minion configuration or a pillar must be set containing

mine_functions:
  network.interfaces: []

accumulo-formula also requires the Salt minion IDs to be resolvable DNS names, or to be present in /etc/hosts; I use hostsfile-formula to populate /etc/hosts.  Also note that this use of the mine data means that you can't have more than one Accumulo cluster tied to a single Salt master, and that its startup sequence requires using some embedded scripts to generate ssh keys (on my personal TODO list but with low priority is solidifying an orchestrate setup that doesn't require this).
 
I've tried a handful of different ways to get this to work, none successful.  The 'first()' always seems to fail.  The reason I'm trying to handle the 'mine.get' is because I want to be able to support this formula in a 'masterless' environment, where different nodes are all the same machine.

As in smushing the HDFS namenode and datanode and the various Accumulo sub-services on to a single managed box, or putting the Salt master on there too?  If you're hand-patching accumulo-formula for this specific setup, you might try just setting

{%- set accumulo_master = salt['grains.get']('fqdn') %}
{%- set accumulo_slaves = [salt['grains.get']('fqdn')] %}

which would ignore the mine and run at least the Accumulo parts on "the current host", whichever that minion is.

Kit Plummer

unread,
Jun 30, 2015, 10:46:42 AM6/30/15
to salt-...@googlegroups.com
I'd actually pasted an in between version of my debugging mess.  I'm actually trying to determine if the dict is not empty, then the 'set'...so I can override the mine.get with a Grain or Pillar config in that case.

So:

if grain.first() is _not_ none:
  set x = grain.first()
else
  set x = 'blah'

But, I believe what is happening is the evaluation of grain.first() fails.  Still poking.

Kit Plummer

unread,
Jun 30, 2015, 10:50:54 AM6/30/15
to salt-...@googlegroups.com
This is a masterless set up, and my limited understanding is that the mine_functions don't apply.  Yeh, I'm trying to create a super small Accumulo set up in Vagrant.

I have a fork of the accumulo-formula - so I could hand patch it.  But I'm hopeful that I can do some "test" that will allow me to run the same code in my real cluster environment as the Vagrant one.  

My problem is that I can't get past the failing mine.get.  Or figure out Jinja enough, to determine what the real issue is in my {% code %}.  Or really, just overcome my ignorance. :)

FWIW, the accumulo-formula works great in a 'real' enviro - so cheers for that.

Nicholas Capo

unread,
Jun 30, 2015, 11:18:07 AM6/30/15
to salt-...@googlegroups.com


Yeah. Cool.

So you can avoid the initial call to first() by doing this:

If grain:
  Set x = grain.keys().first()
Else:
  Set x = blah

Kit Plummer

unread,
Jun 30, 2015, 11:27:34 AM6/30/15
to salt-...@googlegroups.com
Ok, I'm completely baffled.  

{% if salt['mine.get']('roles:accumulo_master', 'network.interfaces', 'grain') %}
  {%- set accumulo_master = salt['mine.get']('roles:accumulo_master', 'network.interfaces', 'grain').keys()|first() %}
{% else %}
  {%- set accumulo_master = gc.get('accumulo_master', pc.get('accumulo_master', 'localhost' )) %}
{%- endif %}
{% if salt['mine.get']('roles:accumulo_slave', 'network.interfaces', 'grain') %}
  {% set accumulo_slaves = salt['mine.get']('roles:accumulo_slave', 'network.interfaces', 'grain').keys() %}
{% else %}
  {%- set accumulo_slaves = gc.get('accumulo_slaves', pc.get('accumulo_slaves', ['localhost'])) %}
{% endif %}

This still gives me:

[CRITICAL] Rendering SLS 'base:accumulo' failed: Jinja variable No first item, sequence was empty.

I'm starting to feel like this is a red-herring.  It shouldn't get to the first(), right?  

Kit Plummer

unread,
Jun 30, 2015, 12:22:08 PM6/30/15
to salt-...@googlegroups.com
Replying to myself for posterity.  Red-herring indeed.  If I do as David suggested and just substitute the mine.get I still get the same "No first item" error.  I have no idea where the real error is then.  Jinja's statement isn't helpful.  I'm not sure how to proceed.  Could this error actually be caused in one of the templated files, and not my Pillar config?  Is there a good way to debug this, print statements somewhere?
Reply all
Reply to author
Forward
0 new messages