calling standard salt states from custom state

525 views
Skip to first unread message

dmar...@zulily.com

unread,
Aug 26, 2014, 11:54:25 AM8/26/14
to salt-...@googlegroups.com

hi,

i'm trying to make a custom salt state and call out to some built-in states like file.directory

the docs and various examples like this https://github.com/saltstack/salt/blob/v0.16.2/salt/states/pkgrepo.py#L163-183 show a custom state calling its own execution module.

the docs also reference cross-calling between execution modules.

so I assumed that anything usable from an .sls would also be usable from a custom state like so:

_states/tarball.py

def installed(name, **kwargs):
  if not kwargs.has_key('archive_name'):
    raise Exception('missing required arg archive_name')
  __salt__['file.directory'](
    name=kwargs['archive_name'],
    user='root',
    group= 'root',
    mode= '0755',
    makedirs= True,
    onlyif= '/usr/bin/stat %' % kwargs['archive_name'])

etc

no good though:


  File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1379, in call
    **cdata['kwargs'])
  File "/var/cache/salt/minion/extmods/states/tarball.py", line 5, in installed
    __salt__['file.directory'](
KeyError: 'file.directory'


so is this possible?  i hope i can make use of built-in salt states from my custom state because it will make life easier.






dmar...@zulily.com

unread,
Aug 26, 2014, 12:07:11 PM8/26/14
to salt-...@googlegroups.com

I think my mistake may have been trying to use file state function (file.directory) instead of file module function (file.directory_exists)



Tim O'Guin

unread,
Aug 26, 2014, 12:19:25 PM8/26/14
to salt-...@googlegroups.com
Just FYI, if you wanted to call a state module, you could use the __salt__['state.single'] dict and pass the state module and arguments to that.


On Tue, Aug 26, 2014 at 11:07 AM, <dmar...@zulily.com> wrote:

I think my mistake may have been trying to use file state function (file.directory) instead of file module function (file.directory_exists)



--
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.

dmar...@zulily.com

unread,
Aug 26, 2014, 4:17:48 PM8/26/14
to salt-...@googlegroups.com


thank you. 

i found this somewhere



import salt.loader

def whatever(name, **kwargs):
...
  # calling state from custom state
  # https://github.com/saltstack/salt/issues/3513
  opts = __opts__.copy()
  opts['grains'] = __grains__
  __states__ = salt.loader.states(opts, __salt__)


one problem with salt['state.single']('file.directory'...) is it doesn't seem to return a dict of (status, changes, etc) like __states__['file.directory'](...)


__states__[state] works most of the time but I did manage to get this exception:

          ID: erlang
    Function: tarball.installed
      Result: False
     Comment: An exception occurred in this state: Traceback (most recent call last):

                File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1379, in call
                  **cdata['kwargs'])
                File "/var/cache/salt/minion/extmods/states/tarball.py", line 55, in installed
                  if_missing=kwargs['archive_name'] + '/' + kwargs['archive_relative_directory']
                File "/usr/lib/python2.7/dist-packages/salt/states/archive.py", line 100, in extracted
                  {'saltenv': __env__}
              NameError: global name '__env__' is not defined

seems to be a bug that may be fixed.  https://github.com/saltstack/salt/issues/10773

i am probably not on the latest version and it may be a big undertaking to upgrade.

dmar...@zulily.com

unread,
Aug 26, 2014, 4:22:11 PM8/26/14
to salt-...@googlegroups.com


actually the state.single does return what i need, it was just nested in another dict.

Wolodja Wentland

unread,
Aug 27, 2014, 5:16:37 AM8/27/14
to salt-...@googlegroups.com
On Tue, Aug 26, 2014 at 11:19 -0500, Tim O'Guin wrote:
> Just FYI, if you wanted to call a state module, you could use the __salt__
> ['state.single'] dict and pass the state module and arguments to that.

The different ways to call states, modules, grains, ... from within custom
grains, execution modules, custom states and so on should probably be unified
and documented in a single place. A quick grep for state.single only reveals
references to using it for calling, well, single states from the command line
and does not mention it in the context of custom states at all.

I haven't seen state.single and don't find it particularly intuitive. The
current situation in which __salt__, __grains__, __pillars__ are monkey patched
into modules and different "keys"/functionality being available at different
times is utterly confusing and, IMHO, a bit weird design wise. I'm never quite
sure what I will have access to during module evaluation, runtime or never and
how to call other functions or methods in one of the many salt Python modules.
--
Wolodja <bab...@gmail.com>

4096R/CAF14EFC
081C B7CD FF04 2BA9 94EA 36B2 8B7F 7D30 CAF1 4EFC
signature.asc
Reply all
Reply to author
Forward
0 new messages