nornir-automation / nornir

Pluggable multi-threaded framework with inventory management to help operate collections of devices
https://nornir.readthedocs.io/
Apache License 2.0
1.4k stars 237 forks source link

Runner config.yaml is taking precedence over runner environment variables #726

Closed ktbyers closed 3 years ago

ktbyers commented 3 years ago

I was expecting the precedence to be (highest precedence to lowest precedence):

Inline Python > Environment Variable > Nornir Config File

I was using this simple test case (running Nornir 3.1.1):

from nornir import InitNornir

nr = InitNornir(config_file="config.yaml")
print(f"Runner plugin: {nr.runner}")
print(f"num_workers: {nr.runner.num_workers}")

With the following config.yaml:

$ cat config.yaml 
---
inventory:
  plugin: SimpleInventory
  options:
    host_file: inventory.yaml
runner:
  plugin: threaded
  options:
    num_workers: 7

With the following two environment variables set:

$ env | grep NOR
NORNIR_RUNNER_PLUGIN=serial
NORNIR_RUNNER_OPTIONS={"num_workers": 100}

Running that Python program shows:

$ python foo.py 
Runner plugin: <nornir.plugins.runners.ThreadedRunner object at 0x7f8fa1aad0d0>
num_workers: 7

So the config.yaml file was being preferred over the environment variables.

ktbyers commented 3 years ago

If I comment the following lines in my config.yaml file:

---
inventory:
  plugin: SimpleInventory
  options:
    host_file: inventory.yaml
#runner:
#  plugin: threaded
#  options:
#    num_workers: 7

And switch my program to only print out nr.runner, I now get:

from nornir import InitNornir

nr = InitNornir(config_file="config.yaml")
print(f"Runner plugin: {nr.runner}")
$ python foo.py 
Runner plugin: <nornir.plugins.runners.SerialRunner object at 0x7ff9fbd11a10>

Just to verify that my environment variable is properly set.

I also unset NORNIR_RUNNER_OPTIONS for this test.

ktbyers commented 3 years ago

If I experiment with just num_workers, I also see that the config.yaml wins over the environment variable:

---
inventory:
  plugin: SimpleInventory
  options:
    host_file: inventory.yaml
runner:
  plugin: threaded
  options:
    num_workers: 7
$ env | grep NORNIR
NORNIR_RUNNER_OPTIONS={"num_workers": 100}
from nornir import InitNornir

nr = InitNornir(config_file="config.yaml")
print(f"Runner plugin: {nr.runner}")
print(f"num_workers: {nr.runner.num_workers}")
$ python foo.py 
Runner plugin: <nornir.plugins.runners.ThreadedRunner object at 0x7f809bb66790>
num_workers: 7

I also verified here if I commented out the runner section in config.yaml that my environment variable was working properly (i.e. I would see 100 workers for num_workers).

ktbyers commented 3 years ago

I also as a sanity check tested inline-code for num_workers and it behaved as expected i.e. that the inline code won out over the environment variable and over the config.yaml:

from nornir import InitNornir

# nr = InitNornir(config_file="config.yaml")
nr = InitNornir(config_file="config.yaml", runner={"plugin": "threaded", "options": {"num_workers": 3}})
print(f"Runner plugin: {nr.runner}")
print(f"num_workers: {nr.runner.num_workers}")
$ python foo.py 
Runner plugin: <nornir.plugins.runners.ThreadedRunner object at 0x7f7fe2c99890>
num_workers: 3
ktbyers commented 3 years ago

Never mind...I see that we changed this:

Order of resolution for parameters is now InitNornir > config > environment

from:

https://nornir.readthedocs.io/en/latest/upgrading/2_to_3.html

I will make a different documentation change as there was a reference to the old behavior in the docs.