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

Minion error when calling custom execution module from salt master #41891

Closed
KyleMoser opened this issue Jun 21, 2017 · 4 comments
Closed

Minion error when calling custom execution module from salt master #41891

KyleMoser opened this issue Jun 21, 2017 · 4 comments
Labels
cannot-reproduce cannot be replicated with info/context provided info-needed waiting for more info
Milestone

Comments

@KyleMoser
Copy link

KyleMoser commented Jun 21, 2017

Description of Issue/Question

Salt master does not properly pass arguments to minion execution module when calling LocalClient. I've created a function with the following code
def example(**kwargs): and is in a file called backup.py.

and I'm calling it from python code on the salt master that looks like:

c = salt.client.LocalClient()
c.cmd(sys.argv[1], 'backup.example', **dict)

I've also tried

c = salt.client.LocalClient()
c.cmd(sys.argv[1], 'backup.example', url='testing', url2='testing2')

I've tried calling it tons of different ways. I have a dictionary called 'post' that contains some key/value pairs and contains another dictionary nested inside it. I would like to pass 'post' from the salt master to the salt minion. The documentation implies that **kwargs (e.g., any additional args you pass to the cmd function like my two examples above) will be passed to the execution module as kwargs but that does not happen

Solution:
I did, however, find a solution. I just call it like this c.cmd(sys.argv[1], 'backup.example', kwarg=dict). Then the entire dict gets sent to the minion execution module, although it is strangely duplicated.

###_ Setup
Custom execution module in the _modules directory.

Versions Report

Salt master is 2016.11.5 (Carbon) minion is 2016.11.4

@yagnik
Copy link
Contributor

yagnik commented Jun 22, 2017

@KyleMoser the code is here:

def cmd(self,

Cursory look tells me that kwarg is also a keyword so you probably don't want to use that when calling it in your code.

@KyleMoser
Copy link
Author

KyleMoser commented Jun 22, 2017

@yagnik Thanks. I also tried calling it like c.cmd(sys.argv[1], 'backup.sync', url='testing', other='false') and that doesn't work either. I also tried calling it like c.cmd(sys.argv[1], 'backup.sync', **post) where post is a dictionary, and that didn't work either. In each case, I adjusted my execution module to have various arguments (e.g. I added the appropriate params such as 'url' and 'other' and I also tried using **kwargs as a param). Passing a dictionary just never works like I expect it to based on the documentation.

@Ch3LL
Copy link
Contributor

Ch3LL commented Jun 22, 2017

can you elaborate on your example?

You show def example(url, **kwargs): but you are calling 'backup.sync'

If i use what I think is your test case I see expected behavior.

Custom execution module: backup.py

import salt
import sys
import logging

log = logging.getLogger(__name__)

def example(url, **kwargs):
      log.warning(url)
      log.warning(kwargs)

from python interpreter

>>> c.cmd('*', 'backup.example', kwarg={'url':'testing', 'other' : 'false'})
{'93bc5a7d182d': None}

And i see in the minion log:

2017-06-22 15:30:12,017 [salt.loader.localhost.ext.module.backup  ][WARNING ][1860] testing        
2017-06-22 15:30:12,018 [salt.loader.localhost.ext.module.backup  ][WARNING ][1860] {'__pub_user': 'root', '__pub_arg': [{'url': 'testing', 'other': 'false'}], '__pub_fun': 'backup.example', '__pub_jid': '20170622153011996566', 'other': 'false', '__pub_tgt': '*', '__pub_tgt_type': 'glob', '__pub_ret': ''} 

@Ch3LL Ch3LL added cannot-reproduce cannot be replicated with info/context provided info-needed waiting for more info labels Jun 22, 2017
@Ch3LL Ch3LL added this to the Blocked milestone Jun 22, 2017
@KyleMoser
Copy link
Author

KyleMoser commented Jun 22, 2017

@Ch3LL I apologize for wasting your time, I was really tired yesterday and I totally screwed up my explanation. I still think there is an issue with either the documentation, or with how kwargs are passed from the salt master to the salt minion. I have edited the original post to explain the error better. I will explain again here and attempt to be more specific:

My module is called backup.py and my function looks like this:

def sync(**kwargs):
    LOG.info(str(kwargs))
    return True

I am running a python script on my salt master, and I have a dictionary called post. 'Post' is actually a dictionary containing some key/value pairs, where one of the pairs is a key called 'fields' with a value that is another dictionary.

If I run the following, it works, meaning it prints out my dictionary (which has some string key/val pairs as well as another embedded dictionary inside it):
c.cmd(sys.argv[1], 'backup.sync', kwarg=post)

Whereas if I run the following, there are no errors, but my dictionary is nowhere to be seen in the output:
c.cmd(sys.argv[1], 'backup.sync', **post)

And if I run the following, I get an error "Passed invalid arguments to backup.sync: sync() takes exactly 0 arguments (9 given)":
c.cmd(sys.argv[1], 'backup.sync', post)

Note: I never thought the above would work, I am just including it for completeness. I did, however, think using **post would work since that's supposed to expand the dictionary, and the salt documentation mentions you can use **kwargs.

One final example, if I run the following, there are no errors, but my url and url2 are nowhere to be seen in the output:

c.cmd(sys.argv[1], 'backup.sync', url='test', url2='test2')

In summary, the reason for this bug report is that it is not clear how to pass kwargs to a function. The documentation makes it seem like it can be done, but unless my understanding of Python is incorrect (and I am very new to Python so it's possible), the 'normal' way of passing kwargs simply does not work.

Thanks again for taking a look at this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cannot-reproduce cannot be replicated with info/context provided info-needed waiting for more info
Projects
None yet
Development

No branches or pull requests

3 participants