Skip to content

Commit 1c59d83

Browse files
committed
Use host data for global args (#621)
* Consider host data when collecting global op args. Host data is preferred over the config default, so the order is now: + Operation arguments + Any current deploy arguments + Host data + Config * Add tests for operation arg extraction. * Don't assume `host.data.X` will always return `None`.
1 parent b541b48 commit 1c59d83

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

pyinfra/api/deploy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def decorated_func(*args, **kwargs):
110110
'Deploy called without state/host: {0} ({1})'
111111
).format(func, get_call_location()))
112112

113-
deploy_kwargs, _ = pop_global_op_kwargs(state, kwargs)
113+
deploy_kwargs, _ = pop_global_op_kwargs(state, host, kwargs)
114114

115115
# Name the deploy
116116
deploy_name = getattr(func, 'deploy_name', func.__name__)

pyinfra/api/operation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def decorated_func(*args, **kwargs):
180180
#
181181

182182
# Get the meta kwargs (globals that apply to all hosts)
183-
global_kwargs, global_kwarg_keys = pop_global_op_kwargs(state, kwargs)
183+
global_kwargs, global_kwarg_keys = pop_global_op_kwargs(state, host, kwargs)
184184

185185
# If this op is being called inside another, just return here
186186
# (any unwanted/op-related kwargs removed above).

pyinfra/api/operation_kwargs.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,14 @@ def get_executor_kwarg_keys():
123123
return list(keys)
124124

125125

126-
def pop_global_op_kwargs(state, kwargs):
126+
def pop_global_op_kwargs(state, host, kwargs):
127127
'''
128-
Pop and return operation global keyword arguments.
128+
Pop and return operation global keyword arguments, in preferred order:
129+
130+
+ From the current context (operation kwargs)
131+
+ From any current @deploy context (deploy kwargs)
132+
+ From the host data variables
133+
+ From the config variables
129134
'''
130135

131136
meta_kwargs = state.deploy_kwargs or {}
@@ -149,6 +154,10 @@ def get_kwarg(key, default=None):
149154
if default:
150155
default = default(state.config)
151156

157+
host_default = getattr(host.data, key, None)
158+
if host_default is not None:
159+
default = host_default
160+
152161
value, has_key = get_kwarg(key, default=default)
153162
if handler:
154163
value = handler(state.config, value)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from unittest import TestCase
2+
3+
from pyinfra.api import Config, Inventory, State
4+
from pyinfra.api.operation_kwargs import pop_global_op_kwargs
5+
6+
7+
class TestOperationKwargs(TestCase):
8+
def test_get_from_config(self):
9+
config = Config(SUDO='config-value')
10+
inventory = Inventory((('somehost',), {}))
11+
12+
state = State(config=config, inventory=inventory)
13+
14+
kwargs, keys = pop_global_op_kwargs(state, inventory.get_host('somehost'), {})
15+
assert kwargs['sudo'] == 'config-value'
16+
17+
def test_get_from_host(self):
18+
config = Config(SUDO='config-value')
19+
inventory = Inventory(([('somehost', {'sudo': 'host-value'})], {}))
20+
21+
state = State(config=config, inventory=inventory)
22+
23+
kwargs, keys = pop_global_op_kwargs(state, inventory.get_host('somehost'), {})
24+
assert kwargs['sudo'] == 'host-value'
25+
26+
def test_get_from_state_deploy_kwargs(self):
27+
config = Config(SUDO='config-value')
28+
inventory = Inventory(([('somehost', {'sudo': 'host-value'})], {}))
29+
30+
state = State(config=config, inventory=inventory)
31+
state.deploy_kwargs = {'sudo': 'deploy-kwarg-value'}
32+
33+
kwargs, keys = pop_global_op_kwargs(state, inventory.get_host('somehost'), {})
34+
assert kwargs['sudo'] == 'deploy-kwarg-value'
35+
36+
def test_get_from_kwargs(self):
37+
config = Config(SUDO='config-value')
38+
inventory = Inventory(([('somehost', {'sudo': 'host-value'})], {}))
39+
40+
state = State(config=config, inventory=inventory)
41+
state.deploy_kwargs = {'sudo': 'deploy-kwarg-value'}
42+
43+
kwargs, keys = pop_global_op_kwargs(
44+
state,
45+
inventory.get_host('somehost'),
46+
{'sudo': 'kwarg-value'},
47+
)
48+
assert kwargs['sudo'] == 'kwarg-value'
49+
assert 'sudo' in keys

0 commit comments

Comments
 (0)