Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to access salt dunders from global scope within py pillar templates. #10270

Closed
dlanderson opened this issue Feb 7, 2014 · 3 comments
Closed
Labels
Bug broken, incorrect, or confusing behavior Core relates to code central or existential to Salt P2 Priority 2 severity-medium 3rd level, incorrect or bad functionality, confusing and lacks a work around stale
Milestone

Comments

@dlanderson
Copy link
Contributor

Unable to access salt dunders from global scope within py pillar templates.

(salt-dev)root@salt:/srv/pillar/base# cat top.sls 
base:
  '*':
    - pytest


(salt-dev)root@salt:/srv/pillar/base# cat pytest.sls
#!py

file_roots = __opts__['file_roots']

def run():
    return {__name__: file_roots}


(salt-dev)root@web1:~# salt-call pillar.data
local:
    ----------
    _errors:
        - Rendering SLS 'pytest' failed, render error:
        - name '__opts__' is not defined

Changing the pytest.sls file so that it runs just once without render errors:

(salt-dev)root@salt:/srv/pillar/base# cat pytest.sls
#!py

file_roots = "blah"

def run():
    return {__name__: file_roots}


(salt-dev)root@web1:~# salt-call pillar.data
local:
    ----------
    pytest:
        blah

Now change pytest.sls back to using opts dunder:

(salt-dev)root@salt:/srv/pillar/base# cat pytest.sls
#!py

file_roots = __opts__['file_roots']

def run():
    return {__name__: file_roots}


(salt-dev)root@web1:~# salt-call pillar.data
local:
    ----------
    pytest:
        ----------
        base:
            - /srv/pillar/base

It will stop working again when the master is restarted. Also, if you get it to render once without errors it will only work with that one master thread:

(salt-dev)root@web1:~# for i in `seq 1 10`; do salt-call pillar.data; done
local:
    ----------
    _errors:
        - Rendering SLS 'pytest' failed, render error:
        - name '__opts__' is not defined
local:
    ----------
    pytest:
        ----------
        base:
            - /srv/pillar/base
local:
    ----------
    _errors:
        - Rendering SLS 'pytest' failed, render error:
        - name '__opts__' is not defined
local:
    ----------
    _errors:
        - Rendering SLS 'pytest' failed, render error:
        - name '__opts__' is not defined
local:
    ----------
    pytest:
        ----------
        base:
            - /srv/pillar/base
local:
    ----------
    _errors:
        - Rendering SLS 'pytest' failed, render error:
        - name '__opts__' is not defined
local:
    ----------
    pytest:
        ----------
        base:
            - /srv/pillar/base
local:
    ----------
    _errors:
        - Rendering SLS 'pytest' failed, render error:
        - name '__opts__' is not defined
local:
    ----------
    _errors:
        - Rendering SLS 'pytest' failed, render error:
        - name '__opts__' is not defined
local:
    ----------
    pytest:
        ----------
        base:
            - /srv/pillar/base

The dunders work as expected if accessed within the run() function:

(salt-dev)root@salt:/srv/pillar/base# cat pytest.sls
#!py

def run():
    file_roots = __opts__['file_roots']
    return {__name__: file_roots}
@scoates
Copy link
Contributor

scoates commented Feb 7, 2014

FWIW, I dug into this pretty seriously, earlier this week.
The problem here is that the module code is parsed by imp before the dunders have been added, so if it can't compile, it bails.

The order of operations is roughly:

  1. import the code in your "module" (python parses the module at this time, and fails because there are referenced-yet-undefined variables) https://github.com/saltstack/salt/blob/develop/salt/utils/templates.py#L343
  2. add the dunders https://github.com/saltstack/salt/blob/develop/salt/utils/templates.py#L348
  3. call run https://github.com/saltstack/salt/blob/develop/salt/utils/templates.py#L351

You're right that the workaround is to guard them within a function.
Perhaps the whole thing could be guarded within an outer function, by Salt (or the py renderer) itself?

At the very least, the exception raised by load_source should probably be caught, and a better error message should be passed on to the user.

@basepi
Copy link
Contributor

basepi commented Feb 7, 2014

Thanks for your detective work, @scoates! We definitely should at least improve the error message here, pending a better solution.

@basepi basepi added Bug labels Feb 7, 2014
@basepi basepi added this to the Outstanding Bugs milestone Feb 7, 2014
@basepi basepi modified the milestones: Approved, Outstanding Bugs Apr 21, 2014
@twangboy twangboy added severity-medium 3rd level, incorrect or bad functionality, confusing and lacks a work around Core relates to code central or existential to Salt P2 Priority 2 and removed severity-low 4th level, cosemtic problems, work around exists labels Jul 28, 2015
@stale
Copy link

stale bot commented Dec 4, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.

@stale stale bot added the stale label Dec 4, 2017
@stale stale bot closed this as completed Dec 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug broken, incorrect, or confusing behavior Core relates to code central or existential to Salt P2 Priority 2 severity-medium 3rd level, incorrect or bad functionality, confusing and lacks a work around stale
Projects
None yet
Development

No branches or pull requests

4 participants