-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Exception when using Salt mine from pillar #11509
Comments
Maybe related to bf92ef7 in any way? |
He's using In any case, we'll investigate this. |
I've run into the same master_uri key error problem using a similar mine.get call in a template. |
@zerowolfgang Did you make the mine.get call in a state template or pillar template? |
That gist 404s for me, On Fri, Mar 28, 2014 at 10:41 AM, Jens Rantil notifications@github.comwrote:
|
@JensRantil Pillar. Could I expect the same error in a state template ? |
I don't know, but since I was experiencing this using pillar, too it's probably related to that. |
@cachedout I might have initially posted a gist. I removed it a put the actual error in this issue instead. Is that what you were referring to? |
@JensRantil JFTR, I have confirmed that this is worky in a state file, i.e.:
The same crashses with the master_uri KeyError in a pillar file, which is where I need it to be worky. |
@JensRantil Yes, I think so. Looks like most of the relevant information is in the issue now so I'll take a peek this morning. |
That error may be resolved in #11673. Please have a look at that patch and see if it resolves your concerns. |
Also, I don't believe that querying mine data from a pillar is generally a supported behavior. Is this something that has worked for you in the past? |
No, it's not. If it's not supported I propose printing out a message that it's not supported ;) |
I've never tried it before either, but the docs seem to imply it's doable. JTFR there are those on the salt Google group, and a mention on SO, that claim they have it working in some fashion. |
@zerowolfgang Do you have a link to that discussion where they claim this? |
@JensRantil Yes, and I've both misspoke and misread regarding it though :/ See http://goo.gl/V1JMQH - I guess this only reaffirms the use of mine.get in states. And I see now from your post on the 25th that you've spec'd mine_functions in a pillar file (as in the link) whereas I have not, but the invocations of mine.get have yielded the same error nonetheless, so perhaps @cachedout's last comment re supported behaviour is a factor here. |
Yes, it does work in state files and that's widely supported. However, none of the core devs that I've talked to believe that mine.get inside pillars is a feature that's either documented or supported. I suppose we need to make a final decision on that issue but I wanted to at least alert you that this may be moved into feature work instead of bug fixing if robust pillar+mine integration is necessary. That said, I agree with Jens that we need some form of documentation or alert notice to inform users about possible issues. |
I'm relatively new to salt and am far from wading too deeply into the doco, so I have a question that pertains to the original mine.get attempt in pillar files: I reckon it's safe to assume that what would run as expected in a state file i.e mine.get, pillar.get, or grains.get, will fail if attempted in top level pillars due to not being supported given each really needs to be called in the context of a node state. |
Hi @zerowolfgang. I'm not completely sure certain what you're trying to accomplish but it sounds like you're trying to gather some data from minions after they're deployed and then you want to be able to use that data in state files. If so, have you considered just using custom grains to accomplish what you want? http://docs.saltstack.com/en/latest/topics/targeting/grains.html#writing-grains |
@cachedout Yes what it sounds like is what I've attempted, evidently at the wrong level. I'll have a look at custom grains, so thanks for the suggestion. Sorry for the slow response. Cheers! |
@zerowolfgang Sounds good. Please keep us posted so we can close this issue when appropriate. Thanks! |
@JensRantil originally opened the issue.If he's satisfied with where things are, I'm good if he closes it as well. Danke ! |
@zerowolfgang Thanks for the quick reply. We'll see if @JensRantil wants to close this or leave it open. Thanks! |
@zerowolfgang @cachedout Custom grains are generally only loaded on minions on startup, right? If so, it is not enough for my requirements. Basically I'd want to set a variable conditionally based on another host exists or not. I could set this variable in a Jinja template, but since I'd like to reuse the variable, I would get rather messy with includes etc. I think this issue can be closed after either:
|
+1 for mine in pillars. |
+1 for mine in pillars. Basically what @bersace said. |
+1 |
I've added the following to a custom execution module, allowing me to access the mine from pillars:
This only supports minion_id globbing for lookups, but that could be pretty easily adapted if you need other target types. In my pillars, I can use:
as a drop-in replacement for:
I'm interested to know if anyone has a better work-around - preferably one that doesn't involve forking the salt runner as a separate process. I'd also warn that you need to be sure you can trust the input for 'tgt' and 'fun', as it's not being sanitized and I suspect someone could convince it to do malicious things. Anything that can invoke pillar_mine_get could also invoke cmd.run, but if you can't trust the inputs, don't use this solution. |
@AusIV Very nice. Thanks for this workaround ! |
@AusIV that is a good workaround. In answer to your question about avoiding the shell-out process: the following should be possible now that #26648 is slated for the next 2015.5.6 point-release and the impending 2015.8 release: {% set mine_data = salt['saltutil.runner']('mine.get', tgt='host_glob', fun='network.ip_addrs') %} It uses the old-ish but not well-known saltutil.runner function. Unfortunately, prior to the above pull req, it shadowed the |
I tried to use something like this: Does the solution with |
@genuss: salt-call is a minion command, salt-run is a master command. Pillars get evaluated on the master, so if your master isn't also a minion salt-call won't work. salt-run, on the other hand, should always be present on the master (but you won't be able to use that module on formulas that run on minions). Also, were you accounting for the fact that it's going to hand back a string, but it will be a serialized object? That's why I'm getting the output as json and parsing it. |
It looks like you workaround works much better than mine! Thanks a lot. |
+1 It would be great if it was possible to use Without this I think I may need to kludge it so that it gets this particular data from the state and everything else from the pillars. |
Calling the mine runner as detailed in this comment should be sufficient to close this issue out. Please test accordingly and update this issue if you encounter trouble. 2015.8 is due out shortly (likely this week) and the fix will be in 2015.5.6 as well. We can update the docs to direct master-side operations (Pillar & Orchestrate) to the mine runner and minion-side operations to the mine execution module and I think this can finally be closed. |
👏 Thanks! |
@AusIV - I tried using your execution module example, but it isn't working. When I try to gen the pillar it says it can't find the module. No idea what I am doing wrong... The module is loaded on the minions fine, I see no errors in the minion logs and it shows it copying and loading the module... |
@bentwire: You need to have it set up in the salt master under extension_modules. See here. It's different than execution modules that run on minions, and it's an area of documentation that seems pretty lacking. I think one of my co-workers figured it out from a blog post somewhere, and I just know about it from seeing it done in our code base. I have configured my salt master with:
And the execution module is at |
@AusIV - Awesome! I will try this. Thank you for the quick reply! |
I really don't think that this is an acceptable solution as it forces users to fork formulas whenever they need to incorporate data from the mine. It is nice that it is easier to incorporate it this way, but it is far from a solution to the actual problem, namely that one cannot easily include dynamic data in the pillar as we conflate mine configuration and pillar rendering. A step in the right direction would be the implementation of static pillars as discussed in #23910 |
Totally agree. Arguments to a mine call should not be hard-coded in a publically available formula. But since you cannot reference Pillar from within Pillar, there's no good way to package such a formula other than docs. |
Here we reuse pillar in pillars with Jinja. {% import_yaml 'other/pillar.sls' as other -%}
formula:
foo: 0
bar: {{ other.other.bar }}
baz: {{ salt['pillarmine.get']('func') }} In order to get full settings out of pillar, we combine {% set defaults = salt['defaults.get']('formula') -%}
{% load_pillar as pillars -%}
foo: 128
baz: {{ salt['pillarmine.get']('func') }}
{% endload -%}
{% set pillars = salt['grains.filter_by']({
'default': defaults,
}, merge=pillars) -%}
formula:
{{ pillars|yaml(False)|indent(2) }} See #26903 |
Ooh, nice addition.
|
@bersace Can you please explain this a little bit more? |
Here is the import logging
import yaml
logger = logging.getLogger(__name__)
def get(tgt, fun, tgt_type='glob'):
cmd_run = __salt__['cmd.run'] # noqa
cmd = "salt-run mine.get --out yaml '%s' %s tgt_type=%s" % (
tgt, fun, tgt_type)
logger.debug("Querying mine with %r", cmd)
output = cmd_run(cmd)
logger.debug("Got mine result %s", output)
return yaml.load(output) |
@bogdanr of course. The goal is to feed formulas map.jinja with only namespaced pillars with pillar deduplication. No grains, no cross formula pillar reference, no mine. So we want to have importable pillars containing defaults, regular pillars, mine and even grains logic. For this we use the power of jinja and salt modules to merge values in order and render the final values as yaml. Note that modules in pillars are executed on master side. So you don't have # First, loads defaults from formula in jinja. This load `base:formula/defaults.yml` from `file_roots`, not pillar_roots.
{% set defaults = salt['defaults.get']('formula') -%}
# Then, loads regular pillar, namespaceless in jinja
{% load_pillar as pillars -%}
foo: 128
# You can use the hack in pillarmine module to fetch mine values from pillar.
baz: {{ salt['pillarmine.get']('func') }}
{% endload -%}
# Now, merge defaults and pillars to get final pillar
{% set pillars = salt['grains.filter_by']({
'default': defaults,
}, merge=pillars) -%}
# Finally, render pillar namespaced.
formula:
{{ pillars|yaml(False)|indent(2) }} You can now reuse pillars in another pillar in these way : # Import the yaml in jinja. You know that with the preceding logic, you have final values, including defaults.
{% import_yaml 'formula.sls' as formulap -%}
{% set formula = formulap.formula -%}
bar:
# Reuse a value just like you do in a formula
name: {{ formula.foo }} You can also directly import jinja variables, but that's a new API you have to respect, and it does not work on all pillars. {% from 'formula.sls' import pillars as formula -%}
bar:
name: {{ formula.foo }} |
regarding #11509 (comment): incase anyone is having the same problem - if you have minions that require a significant amount of mine data, this method will timeout (saltReqTimeoutError) when the minion runs state.highstate. until mine data becomes available in pillar, a hack is to cache the mine data on cron on the salt master. this is detailed here: #21403 (comment) |
This works:
(no, I wasn't expecting any data, nor an exception)
The text was updated successfully, but these errors were encountered: