saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Install Salt from the Salt package repositories here:
https://docs.saltproject.io/salt/install-guide/en/latest/
Apache License 2.0
14.18k stars 5.48k forks source link

Grains refresh/reload failed #57468

Open AmiramMaimon opened 4 years ago

AmiramMaimon commented 4 years ago

I'm trying to reload the minion grains during a sls run with no success. I have tried to use:

Using each of the above function I failed to reload the grains during the state run.

Consider the following example:

before:
  cmd.run:
    - name: echo "{{ grains['dns'] }}"

echo "domain test" >> /etc/resolv.conf:
  cmd.run: []

after:
  cmd.run:
    - name: echo "{{ grains['dns'] }}"

At the before id I expect the domain field to be empty while on the after id I expect that the domain field would containtest Another example, when i file.managed the grains.conf file I want that the grains change will take affect on the current run.

How can I achieve that?

I'm running on Ubuntu 16.04 with salt-minion and salt-master version 3000.3

sagetherage commented 3 years ago

the Core team will not be able to get to this in Aluminium but we will review a PR if anyone in the community wants to submit one, moving to Silicon

garethgreenaway commented 3 years ago

@AmiramMaimon Apologies for the delay on this one. The major root of the issue here is that the state file is only rendered once and when it is initially rendered the contents of the grain is empty. If you try the following state you'll see that the grains returned from the call to grains.items are updated following the refresh.

before:
  test.nop:
    - name: "{{ grains['dns'] }}"

write_resolv:
  cmd.run:
    - name: 'echo "domain test" >> /etc/resolv.conf'

grains_refresh:
  module.run:
   - saltutil.refresh_grains: []
   - reload_grains: true

grains_read:
  module.run:
   - grains.get:
     - key: dns

after:
  test.nop:
    - name: "{{ grains['dns'] }}"
AmiramMaimon commented 3 years ago

I have tried the following:

grains_refresh:
  module.run:
   - saltutil.refresh_grains: []
   - reload_grains: true

The only new part is:

grains_read:
  module.run:
   - grains.get:
     - key: dns

Why do I need it for? It will cause a re-rendering of the grains? (I would expect the first part to do it as well)

garethgreenaway commented 3 years ago

@AmiramMaimon That new part was there to illustrate that the grains are being updated. Each state file is only rendered once by the jinja renderer, so the grains are updated but the grains dictionary that is being referenced in the after section is still the same value as the grains dictionary in the before section.

AmiramMaimon commented 3 years ago

So if I want to use the updated grains I need to call the module, as presented at the grain_read section?

Correct me if I'm wrong here, is this the best practice to achieve this?? There is no way to cause the grains state file to be re-renderer so the grains dictionary will be updated as well? (sounds like a feature)

This problem causes me to run the salt-minion, at least, twice in order to finish the configuration. At the first run it will effect some of the server grains data and at the second run it will use the new data to complete some of its tasks.

garethgreenaway commented 2 years ago

@AmiramMaimon Apologies for the delay, circling back on this one. If we look back at your original state where you're looking at the value of dns in the available grains, then updating the file which is the basis of that grain in the same state, because the state has been rendered already the values of the grains are not going to be updated until you run the state again which would cause the state to be rendered again with the updated grains. Anything that is wrapped in jinja templating will be rendered once and only once.

What is the problem that you're looking to solve by updating the grain and then using it that update later?