Skip to content

Commit ffd6591

Browse files
Enable passing extra data via pyinfra.local.include (pyinfra-dev#1226)
1 parent b110388 commit ffd6591

File tree

5 files changed

+59
-15
lines changed

5 files changed

+59
-15
lines changed

docs/using-operations.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,37 @@ Including files can be used to break out operations across multiple files. Files
227227
# Include & call all the operations in tasks/install_something.py
228228
local.include("tasks/install_something.py")
229229
230+
Additional data can be passed across files via the ``data`` param to parameterize tasks and is available in ``host.data``. For example `tasks/create_user.py` could look like:
231+
232+
.. code:: python
233+
234+
from getpass import getpass
235+
236+
from pyinfra import host
237+
from pyinfra.operations import server
238+
239+
group = host.data.get("group")
240+
user = host.data.get("user")
241+
242+
server.group(
243+
name=f"Ensure {group} is present",
244+
group=group,
245+
)
246+
server.user(
247+
name=f"Ensure {user} is present",
248+
user=user,
249+
group=group,
250+
)
251+
252+
And and be called by other deploy scripts or tasks:
253+
254+
.. code:: python
255+
256+
from pyinfra import local
257+
258+
for group, user in (("admin", "Bob"), ("admin", "Joe")):
259+
local.include("tasks/create_user.py", data={"group": group, "user": user})
260+
230261
See more in :doc:`examples: groups & roles <./examples/groups_roles>`.
231262

232263

pyinfra/local.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from os import path
2+
from typing import Optional
23

34
import click
45

@@ -10,7 +11,7 @@
1011
from pyinfra.context import ctx_state
1112

1213

13-
def include(filename: str):
14+
def include(filename: str, data: Optional[dict] = None):
1415
"""
1516
Executes a local python file within the ``pyinfra.state.cwd``
1617
directory.
@@ -33,7 +34,7 @@ def include(filename: str):
3334

3435
from pyinfra_cli.util import exec_file
3536

36-
with host.deploy(path.relpath(filename, state.cwd), None, None, in_deploy=False):
37+
with host.deploy(path.relpath(filename, state.cwd), None, data, in_deploy=False):
3738
exec_file(filename)
3839

3940
# One potential solution to the above is to add local as an actual

tests/test_cli/deploy/deploy.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ def my_deploy():
4747
# Include the whole file again, but for all hosts
4848
local.include(path.join("tasks", "a_task.py"))
4949

50+
# Include a deploy file, with custom specified data
51+
local.include(path.join("tasks", "b_task.py"), data={"keyword": "Important", "id": 1})
52+
5053
# Execute the @deploy function
5154
my_deploy()
5255

tests/test_cli/deploy/tasks/b_task.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from pyinfra import host
2+
from pyinfra.operations import server
3+
4+
server.shell(
5+
name=f"{host.data.get('keyword')} task operation",
6+
commands=f"echo {host.data.get('id')}",
7+
)

tests/test_cli/test_cli_deploy.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,28 @@ def _assert_op_data(self, correct_op_name_and_host_names):
4343
assert executed is False
4444

4545
def test_deploy(self):
46-
task_file_path = path.join("tasks", "a_task.py")
46+
a_task_file_path = path.join("tasks", "a_task.py")
47+
b_task_file_path = path.join("tasks", "b_task.py")
4748
nested_task_path = path.join("tasks", "another_task.py")
4849
correct_op_name_and_host_names = [
4950
("First main operation", True), # true for all hosts
5051
("Second main operation", ("somehost",)),
51-
("{0} | First task operation".format(task_file_path), ("anotherhost",)),
52-
("{0} | Task order loop 1".format(task_file_path), ("anotherhost",)),
53-
("{0} | 2nd Task order loop 1".format(task_file_path), ("anotherhost",)),
54-
("{0} | Task order loop 2".format(task_file_path), ("anotherhost",)),
55-
("{0} | 2nd Task order loop 2".format(task_file_path), ("anotherhost",)),
52+
("{0} | First task operation".format(a_task_file_path), ("anotherhost",)),
53+
("{0} | Task order loop 1".format(a_task_file_path), ("anotherhost",)),
54+
("{0} | 2nd Task order loop 1".format(a_task_file_path), ("anotherhost",)),
55+
("{0} | Task order loop 2".format(a_task_file_path), ("anotherhost",)),
56+
("{0} | 2nd Task order loop 2".format(a_task_file_path), ("anotherhost",)),
5657
(
57-
"{0} | {1} | Second task operation".format(task_file_path, nested_task_path),
58+
"{0} | {1} | Second task operation".format(a_task_file_path, nested_task_path),
5859
("anotherhost",),
5960
),
60-
("{0} | First task operation".format(task_file_path), True),
61-
("{0} | Task order loop 1".format(task_file_path), True),
62-
("{0} | 2nd Task order loop 1".format(task_file_path), True),
63-
("{0} | Task order loop 2".format(task_file_path), True),
64-
("{0} | 2nd Task order loop 2".format(task_file_path), True),
65-
("{0} | {1} | Second task operation".format(task_file_path, nested_task_path), True),
61+
("{0} | First task operation".format(a_task_file_path), True),
62+
("{0} | Task order loop 1".format(a_task_file_path), True),
63+
("{0} | 2nd Task order loop 1".format(a_task_file_path), True),
64+
("{0} | Task order loop 2".format(a_task_file_path), True),
65+
("{0} | 2nd Task order loop 2".format(a_task_file_path), True),
66+
("{0} | {1} | Second task operation".format(a_task_file_path, nested_task_path), True),
67+
("{0} | Important task operation".format(b_task_file_path), True),
6668
("My deploy | First deploy operation", True),
6769
("My deploy | My nested deploy | First nested deploy operation", True),
6870
("My deploy | Second deploy operation", True),

0 commit comments

Comments
 (0)