pyinfra 3.0b0__py2.py3-none-any.whl → 3.0b2__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. pyinfra/api/__init__.py +3 -0
  2. pyinfra/api/arguments.py +12 -5
  3. pyinfra/api/arguments_typed.py +19 -6
  4. pyinfra/api/command.py +5 -3
  5. pyinfra/api/config.py +115 -13
  6. pyinfra/api/connectors.py +5 -2
  7. pyinfra/api/exceptions.py +19 -0
  8. pyinfra/api/facts.py +34 -33
  9. pyinfra/api/host.py +51 -12
  10. pyinfra/api/inventory.py +4 -0
  11. pyinfra/api/operation.py +88 -42
  12. pyinfra/api/operations.py +10 -11
  13. pyinfra/api/state.py +11 -2
  14. pyinfra/api/util.py +24 -16
  15. pyinfra/connectors/base.py +4 -7
  16. pyinfra/connectors/chroot.py +5 -6
  17. pyinfra/connectors/docker.py +13 -19
  18. pyinfra/connectors/dockerssh.py +5 -4
  19. pyinfra/connectors/local.py +7 -7
  20. pyinfra/connectors/ssh.py +46 -25
  21. pyinfra/connectors/terraform.py +9 -6
  22. pyinfra/connectors/util.py +7 -8
  23. pyinfra/connectors/vagrant.py +11 -10
  24. pyinfra/context.py +1 -0
  25. pyinfra/facts/apk.py +2 -0
  26. pyinfra/facts/apt.py +2 -0
  27. pyinfra/facts/brew.py +2 -0
  28. pyinfra/facts/bsdinit.py +2 -0
  29. pyinfra/facts/cargo.py +2 -0
  30. pyinfra/facts/choco.py +3 -1
  31. pyinfra/facts/deb.py +9 -4
  32. pyinfra/facts/dnf.py +2 -0
  33. pyinfra/facts/docker.py +2 -0
  34. pyinfra/facts/files.py +2 -0
  35. pyinfra/facts/gem.py +2 -0
  36. pyinfra/facts/gpg.py +2 -0
  37. pyinfra/facts/hardware.py +30 -22
  38. pyinfra/facts/launchd.py +2 -0
  39. pyinfra/facts/lxd.py +2 -0
  40. pyinfra/facts/mysql.py +12 -6
  41. pyinfra/facts/npm.py +1 -0
  42. pyinfra/facts/openrc.py +2 -0
  43. pyinfra/facts/pacman.py +6 -2
  44. pyinfra/facts/pip.py +2 -0
  45. pyinfra/facts/pkg.py +2 -0
  46. pyinfra/facts/pkgin.py +2 -0
  47. pyinfra/facts/postgres.py +168 -0
  48. pyinfra/facts/postgresql.py +5 -162
  49. pyinfra/facts/rpm.py +12 -9
  50. pyinfra/facts/server.py +10 -13
  51. pyinfra/facts/snap.py +2 -0
  52. pyinfra/facts/systemd.py +28 -10
  53. pyinfra/facts/upstart.py +2 -0
  54. pyinfra/facts/util/packaging.py +3 -2
  55. pyinfra/facts/vzctl.py +2 -0
  56. pyinfra/facts/xbps.py +2 -0
  57. pyinfra/facts/yum.py +2 -0
  58. pyinfra/facts/zypper.py +2 -0
  59. pyinfra/operations/apk.py +3 -1
  60. pyinfra/operations/apt.py +16 -18
  61. pyinfra/operations/brew.py +10 -8
  62. pyinfra/operations/bsdinit.py +5 -3
  63. pyinfra/operations/cargo.py +3 -1
  64. pyinfra/operations/choco.py +3 -1
  65. pyinfra/operations/dnf.py +15 -19
  66. pyinfra/operations/files.py +86 -69
  67. pyinfra/operations/gem.py +3 -1
  68. pyinfra/operations/git.py +18 -16
  69. pyinfra/operations/iptables.py +33 -25
  70. pyinfra/operations/launchd.py +5 -6
  71. pyinfra/operations/lxd.py +7 -4
  72. pyinfra/operations/mysql.py +57 -53
  73. pyinfra/operations/npm.py +8 -1
  74. pyinfra/operations/openrc.py +5 -3
  75. pyinfra/operations/pacman.py +4 -5
  76. pyinfra/operations/pip.py +16 -9
  77. pyinfra/operations/pkg.py +3 -1
  78. pyinfra/operations/pkgin.py +3 -1
  79. pyinfra/operations/postgres.py +349 -0
  80. pyinfra/operations/postgresql.py +18 -335
  81. pyinfra/operations/puppet.py +3 -1
  82. pyinfra/operations/python.py +7 -3
  83. pyinfra/operations/selinux.py +42 -16
  84. pyinfra/operations/server.py +48 -43
  85. pyinfra/operations/snap.py +3 -1
  86. pyinfra/operations/ssh.py +12 -10
  87. pyinfra/operations/systemd.py +13 -9
  88. pyinfra/operations/sysvinit.py +6 -4
  89. pyinfra/operations/upstart.py +5 -3
  90. pyinfra/operations/util/files.py +24 -16
  91. pyinfra/operations/util/packaging.py +53 -37
  92. pyinfra/operations/util/service.py +18 -13
  93. pyinfra/operations/vzctl.py +12 -10
  94. pyinfra/operations/xbps.py +3 -1
  95. pyinfra/operations/yum.py +14 -18
  96. pyinfra/operations/zypper.py +8 -9
  97. pyinfra/version.py +5 -2
  98. {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/METADATA +31 -29
  99. pyinfra-3.0b2.dist-info/RECORD +163 -0
  100. {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/WHEEL +1 -1
  101. pyinfra_cli/commands.py +3 -2
  102. pyinfra_cli/inventory.py +38 -19
  103. pyinfra_cli/main.py +2 -0
  104. pyinfra_cli/prints.py +27 -105
  105. pyinfra_cli/util.py +3 -1
  106. tests/test_api/test_api_deploys.py +5 -5
  107. tests/test_api/test_api_operations.py +5 -5
  108. tests/test_connectors/test_ssh.py +105 -0
  109. tests/test_connectors/test_terraform.py +11 -8
  110. tests/test_connectors/test_vagrant.py +6 -6
  111. pyinfra-3.0b0.dist-info/RECORD +0 -162
  112. pyinfra_cli/inventory_dsl.py +0 -23
  113. {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/LICENSE.md +0 -0
  114. {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/entry_points.txt +0 -0
  115. {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/top_level.txt +0 -0
@@ -500,6 +500,57 @@ class TestSSHConnector(TestCase):
500
500
  get_pty=False,
501
501
  )
502
502
 
503
+ @patch("pyinfra.connectors.util.getpass")
504
+ @patch("pyinfra.connectors.ssh.SSHClient")
505
+ def test_run_shell_command_sudo_password_automatic_prompt_with_special_chars_in_password(
506
+ self,
507
+ fake_ssh_client,
508
+ fake_getpass,
509
+ ):
510
+ fake_ssh = MagicMock()
511
+ first_fake_stdout = MagicMock()
512
+ second_fake_stdout = MagicMock()
513
+ third_fake_stdout = MagicMock()
514
+
515
+ first_fake_stdout.__iter__.return_value = ["sudo: a password is required\r"]
516
+ second_fake_stdout.__iter__.return_value = ["/tmp/pyinfra-sudo-askpass-XXXXXXXXXXXX"]
517
+
518
+ fake_ssh.exec_command.side_effect = [
519
+ (MagicMock(), first_fake_stdout, MagicMock()), # command w/o sudo password
520
+ (MagicMock(), second_fake_stdout, MagicMock()), # SUDO_ASKPASS_COMMAND
521
+ (MagicMock(), third_fake_stdout, MagicMock()), # command with sudo pw
522
+ ]
523
+
524
+ fake_ssh_client.return_value = fake_ssh
525
+ fake_getpass.return_value = "p@ss'word';"
526
+
527
+ inventory = make_inventory(hosts=("somehost",))
528
+ State(inventory, Config())
529
+ host = inventory.get_host("somehost")
530
+ host.connect()
531
+
532
+ command = "echo Šablony"
533
+ first_fake_stdout.channel.recv_exit_status.return_value = 1
534
+ second_fake_stdout.channel.recv_exit_status.return_value = 0
535
+ third_fake_stdout.channel.recv_exit_status.return_value = 0
536
+
537
+ out = host.run_shell_command(command, _sudo=True, print_output=True)
538
+ assert len(out) == 2
539
+
540
+ status, output = out
541
+ assert status is True
542
+
543
+ fake_ssh.exec_command.assert_any_call(("sudo -H -n sh -c 'echo Šablony'"), get_pty=False)
544
+
545
+ fake_ssh.exec_command.assert_called_with(
546
+ (
547
+ "env SUDO_ASKPASS=/tmp/pyinfra-sudo-askpass-XXXXXXXXXXXX "
548
+ """PYINFRA_SUDO_PASSWORD='p@ss'"'"'word'"'"';' """
549
+ "sudo -H -A -k sh -c 'echo Šablony'"
550
+ ),
551
+ get_pty=False,
552
+ )
553
+
503
554
  # SSH file put/get tests
504
555
  #
505
556
 
@@ -1001,3 +1052,57 @@ class TestSSHConnector(TestCase):
1001
1052
  "not-another-file",
1002
1053
  print_output=True,
1003
1054
  )
1055
+
1056
+ @patch("pyinfra.connectors.ssh.SSHClient")
1057
+ @patch("pyinfra.connectors.ssh.sleep")
1058
+ def test_ssh_connect_fail_retry(self, fake_sleep, fake_ssh_client):
1059
+ for exception_class in (
1060
+ SSHException,
1061
+ gaierror,
1062
+ socket_error,
1063
+ EOFError,
1064
+ ):
1065
+ fake_sleep.reset_mock()
1066
+ fake_ssh_client.reset_mock()
1067
+
1068
+ inventory = make_inventory(
1069
+ hosts=("unresposivehost",), override_data={"ssh_connect_retries": 1}
1070
+ )
1071
+ State(inventory, Config())
1072
+
1073
+ unresposivehost = inventory.get_host("unresposivehost")
1074
+ assert unresposivehost.data.ssh_connect_retries == 1
1075
+
1076
+ fake_ssh_client().connect.side_effect = exception_class()
1077
+
1078
+ with self.assertRaises(ConnectError):
1079
+ unresposivehost.connect(show_errors=False, raise_exceptions=True)
1080
+
1081
+ fake_sleep.assert_called_once()
1082
+ assert fake_ssh_client().connect.call_count == 2
1083
+
1084
+ @patch("pyinfra.connectors.ssh.SSHClient")
1085
+ @patch("pyinfra.connectors.ssh.sleep")
1086
+ def test_ssh_connect_fail_success(self, fake_sleep, fake_ssh_client):
1087
+ for exception_class in (
1088
+ SSHException,
1089
+ gaierror,
1090
+ socket_error,
1091
+ EOFError,
1092
+ ):
1093
+ fake_sleep.reset_mock()
1094
+ fake_ssh_client.reset_mock()
1095
+
1096
+ inventory = make_inventory(
1097
+ hosts=("unresposivehost",), override_data={"ssh_connect_retries": 1}
1098
+ )
1099
+ State(inventory, Config())
1100
+
1101
+ unresposivehost = inventory.get_host("unresposivehost")
1102
+ assert unresposivehost.data.ssh_connect_retries == 1
1103
+
1104
+ fake_ssh_client().connect.side_effect = [exception_class(), MagicMock()]
1105
+
1106
+ unresposivehost.connect(show_errors=False, raise_exceptions=True)
1107
+ fake_sleep.assert_called_once()
1108
+ assert fake_ssh_client().connect.call_count == 2
@@ -7,20 +7,23 @@ from pyinfra.connectors.terraform import TerraformInventoryConnector
7
7
 
8
8
 
9
9
  class TestTerraformConnector(TestCase):
10
- def test_make_names_data_no_output_key(self):
11
- with self.assertRaises(InventoryError) as context:
12
- list(TerraformInventoryConnector.make_names_data())
13
-
14
- assert context.exception.args[0] == "No Terraform output key!"
15
-
16
10
  @patch("pyinfra.connectors.terraform.local.shell")
17
11
  def test_make_names_data_no_output(self, fake_shell):
18
- fake_shell.return_value = json.dumps({})
12
+ fake_shell.return_value = json.dumps(
13
+ {
14
+ "hello": {
15
+ "world": [],
16
+ },
17
+ },
18
+ )
19
19
 
20
20
  with self.assertRaises(InventoryError) as context:
21
21
  list(TerraformInventoryConnector.make_names_data("output_key"))
22
22
 
23
- assert context.exception.args[0] == "No Terraform output with key: `output_key`"
23
+ assert (
24
+ context.exception.args[0]
25
+ == "No Terraform output with key: `output_key`, valid keys:\n - hello.world"
26
+ )
24
27
 
25
28
  @patch("pyinfra.connectors.terraform.local.shell")
26
29
  def test_make_names_data_invalid_output(self, fake_shell):
@@ -69,13 +69,13 @@ class TestVagrantConnector(TestCase):
69
69
  )
70
70
  @patch("pyinfra.connectors.vagrant.path.exists", lambda path: True)
71
71
  def test_make_names_data_with_options(self):
72
- data = VagrantInventoryConnector.make_names_data()
72
+ data = list(VagrantInventoryConnector.make_names_data())
73
73
 
74
74
  assert data == [
75
75
  (
76
76
  "@vagrant/ubuntu16",
77
77
  {
78
- "ssh_port": "2222",
78
+ "ssh_port": 2222,
79
79
  "ssh_user": "vagrant",
80
80
  "ssh_hostname": "127.0.0.1",
81
81
  "ssh_key": "path/to/key",
@@ -85,7 +85,7 @@ class TestVagrantConnector(TestCase):
85
85
  (
86
86
  "@vagrant/centos7",
87
87
  {
88
- "ssh_port": "2200",
88
+ "ssh_port": 2200,
89
89
  "ssh_user": "vagrant",
90
90
  "ssh_hostname": "127.0.0.1",
91
91
  "ssh_key": "path/to/key",
@@ -103,13 +103,13 @@ class TestVagrantConnector(TestCase):
103
103
  ]
104
104
 
105
105
  def test_make_names_data_with_limit(self):
106
- data = VagrantInventoryConnector.make_names_data(limit=("ubuntu16",))
106
+ data = list(VagrantInventoryConnector.make_names_data(name=("ubuntu16",)))
107
107
 
108
108
  assert data == [
109
109
  (
110
110
  "@vagrant/ubuntu16",
111
111
  {
112
- "ssh_port": "2222",
112
+ "ssh_port": 2222,
113
113
  "ssh_user": "vagrant",
114
114
  "ssh_hostname": "127.0.0.1",
115
115
  "ssh_key": "path/to/key",
@@ -120,4 +120,4 @@ class TestVagrantConnector(TestCase):
120
120
 
121
121
  def test_make_names_data_no_matches(self):
122
122
  with self.assertRaises(InventoryError):
123
- VagrantInventoryConnector.make_names_data(limit="nope")
123
+ list(VagrantInventoryConnector.make_names_data(name="nope"))
@@ -1,162 +0,0 @@
1
- pyinfra/__init__.py,sha256=7ZcKHGWk7_nYxsYrbFBB_vJr-J-Ddbc56ZS4sk5ArVw,535
2
- pyinfra/__main__.py,sha256=aVd00glLz5CMJGXgt1XxbOvC2HluqaowoTOjxgIpBaA,47
3
- pyinfra/context.py,sha256=4oPK1wsLL4aG5CJtt7Ufe_4D3knrBeZaeZWlU979JNg,3394
4
- pyinfra/local.py,sha256=0bpIRCyDKM6i_jA1i8Ej2qr_iWIF9cUYWutXNdLj8po,2751
5
- pyinfra/progress.py,sha256=X3hXZ4Flh_L9FE4ZEWxWoG0R4dA5UPd1FCO-Exd5Xtc,4193
6
- pyinfra/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- pyinfra/version.py,sha256=hAgEPHVJVjA2I-rI0gy038UAPVKcmulk-3dZLOmkYrI,153
8
- pyinfra/api/__init__.py,sha256=_gId0L-DYg7A1aofFN5ra--GBE2sq7hpobjL470OhTc,888
9
- pyinfra/api/arguments.py,sha256=iOtGiQvRhh8gk0spesH5i0ccDSwEQr2ri6xKL0ADduM,9688
10
- pyinfra/api/arguments_typed.py,sha256=OYB4uEGYogKZV2Amz9fosQEqi9hrkU1eDpWThMX3_Vk,2201
11
- pyinfra/api/command.py,sha256=KGhAnaxZGZv5NJa0-aOgu2g9nOYTsdjlCaFHR6QO53E,7176
12
- pyinfra/api/config.py,sha256=G1ZNHw26G1QyqEBU6AuFsK3jVKdgW-VPqE9WZgtlzkg,4221
13
- pyinfra/api/connect.py,sha256=Z9wusMLR_jBkKKk5D4AUOj8LHl3H5MsNO5FxAeR4jac,1416
14
- pyinfra/api/connectors.py,sha256=SLmKtoN4cXvcQz9IgWSPI-d3ZMzJ09pcvka42Fiuo7s,544
15
- pyinfra/api/deploy.py,sha256=xo4F7URUf3xzIChRHZn4zwqs_WTjLjZNC9i9eQjAFk8,2756
16
- pyinfra/api/exceptions.py,sha256=uzMTtTWXwUGNj5F3z9EOyMSdVkmqurZUdZGd9P_F-xQ,1445
17
- pyinfra/api/facts.py,sha256=ub2LGAcO2K6ofZXQwQSvd6z04_Fc0iez1A6ZQ0Dxec4,10283
18
- pyinfra/api/host.py,sha256=8Ed1pSKmzApX6BfOPXVNmIuN8nHog77qry_5I7mYO3I,12394
19
- pyinfra/api/inventory.py,sha256=83ttxbGbIwN2tvmVTW68fumIDXNMk48qvL0NxwGPkNs,7663
20
- pyinfra/api/operation.py,sha256=HKcTBmWqdHvGpjAXce9Cbx0WLYOdwFvwBc2UiFzhWHA,13225
21
- pyinfra/api/operations.py,sha256=v2WY6lVUoyGRP3bwIM0cgrJEO5HpM1l2eFwRvOQmSpI,10921
22
- pyinfra/api/state.py,sha256=nMPGmNGsEuUDcUU0rp3ky3PA-c2jhrocK-A5NJcPTIc,12526
23
- pyinfra/api/util.py,sha256=TkUlcMPIrLGxRQY19CvCXL1H_20DjFTmFL0QbFqQ0gw,11977
24
- pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- pyinfra/connectors/base.py,sha256=HYlAcup7kNsrzNjw3PyPvt1PESDQadGt_M2hQM8vKQQ,3754
26
- pyinfra/connectors/chroot.py,sha256=mtrQO3wsJj3jlp7bZR0if_LghWjAacEAgBYZw9ysiNo,5963
27
- pyinfra/connectors/docker.py,sha256=nXvtj1J-8wFtG1UkoV_6_NxPeSgvn1uA0pJXGJMfysw,8954
28
- pyinfra/connectors/dockerssh.py,sha256=V4G2g9dRPwDj0UxvGBRM93IHSpGpO5PiBdWJ4KsKjbg,8943
29
- pyinfra/connectors/local.py,sha256=-ofyZA9trondAyzhYnGqk15HtuZdo0gl-N1GHOu_rG0,6937
30
- pyinfra/connectors/ssh.py,sha256=YNbpNAy67pSzlhlVcz9YQPlcBhVVJ5nTrBCF6UL_UnY,20263
31
- pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
32
- pyinfra/connectors/terraform.py,sha256=e7-azZfJpe51UwCWwMRHExup1ePq6AiAyIwB9cu9Fbw,3541
33
- pyinfra/connectors/util.py,sha256=_R5QEyP0A1LBupJ7LPAJeqmWPcPwp_69k9eqFRZkp6A,11321
34
- pyinfra/connectors/vagrant.py,sha256=lUCC3cH8CAmGphDqIfzHSueWYp9jgKldH2MatG0zCv0,4697
35
- pyinfra/connectors/sshuserclient/__init__.py,sha256=Qc4RO2wknSWIiNTwOeQ0y2TeiuKHmyWDW2Dz4MOo9CE,44
36
- pyinfra/connectors/sshuserclient/client.py,sha256=7YSd3QckZuPDRnKzy2FfG3J8zp7CY-jny8tbWwxvKro,9720
37
- pyinfra/connectors/sshuserclient/config.py,sha256=UMwkvTgAIS7__re6Wz_pwH6EU4kO1-uMQ5zuFakH0v4,2721
38
- pyinfra/facts/__init__.py,sha256=myTXSOZmAqmU88Fyifn035h9Lr6Gj2mlka_jDcXyKGw,347
39
- pyinfra/facts/apk.py,sha256=2-Hz4I_7iLU06Y0T9_JX5Fo3k_FZpgKNGZ_I5KQGTto,482
40
- pyinfra/facts/apt.py,sha256=zqFSPIAaIgHWWg3eGgL-BDX1aqvgiQ7rNc8QrE1LXLg,1999
41
- pyinfra/facts/brew.py,sha256=POnOx3PWzK1B8pbtkI9wBmYSUsG0IblpwrMHZsMC7Og,2266
42
- pyinfra/facts/bsdinit.py,sha256=sx54RAmS7rjTDzLbUWv86UFtfE8H56qokektf5smN30,490
43
- pyinfra/facts/cargo.py,sha256=C_2NIWcDzT5Y6xxnT5TvuhWpLJCQTqVVXK8biiUvhjI,531
44
- pyinfra/facts/choco.py,sha256=CatATw35ToFTgFNO_aXwl7ZSi2Mply47VixOJzK7Dp8,716
45
- pyinfra/facts/deb.py,sha256=aTlXoBsuORIe5cbFV_UbXZZLOskcfrWoyuDg_cSAEFY,1662
46
- pyinfra/facts/dnf.py,sha256=zV_Fx4cq81lyKctDYki65e088kXDAyZiwkEcBDOoLtU,862
47
- pyinfra/facts/docker.py,sha256=0EUskxna88haXeHYJBFUDnUHJcX2QIwwKME_dRcfoiY,1678
48
- pyinfra/facts/files.py,sha256=VJujyRa9FiowXnNJUuDmYk6hJi8DYJYetvOAnatkpcg,11475
49
- pyinfra/facts/gem.py,sha256=bUl8PcXHb5wIw3O4E9YAc0cPzCZQK1IbV_4f3hZht6s,473
50
- pyinfra/facts/git.py,sha256=rk4NS2SQJiosI6eY2eCy_p9kOP4O8UARRjFi16ObE2w,1294
51
- pyinfra/facts/gpg.py,sha256=OCfXW-JQpjyn7jLrluEXjpu9Wr_DE_6eWEsyKVLOnNU,3729
52
- pyinfra/facts/hardware.py,sha256=rEwe5nK6m_c3zLsEpU0x0qSkGCZfKrBlUVhhjAT2Bbo,11402
53
- pyinfra/facts/iptables.py,sha256=sUkywfHZUXnMZF_KshAnyJufrJvZ9fBYnERSRbwOCRE,3374
54
- pyinfra/facts/launchd.py,sha256=NtsaAJh0rncopvuawqqv36kOdFsUdpiYS7e5yCGoXeA,668
55
- pyinfra/facts/lxd.py,sha256=uYmqu8vSzfhM0Ymm15pT4IhI4UbRayC23GM6kSYN1mw,337
56
- pyinfra/facts/mysql.py,sha256=o5qvcxKjW2zXNSr4tLZa1IaNEUz0TVLWy7T9uLlxTm8,5896
57
- pyinfra/facts/npm.py,sha256=c_bU5BoeOfBfZd_qyz2K1ZzzlH_k1VSzjuOiGqC4H8o,674
58
- pyinfra/facts/openrc.py,sha256=IluFop9jskxHnWRJkKlGZZV7nQDOFzhiAMAH0ThyiLo,1350
59
- pyinfra/facts/pacman.py,sha256=SJTdi49nBHk7Gb6ajf2I5PZTHWkqZ_k4npAf695luRs,1001
60
- pyinfra/facts/pip.py,sha256=v6pJCQHOB8DaDgpyrLTz3kKKCSqvLG_zs0uy6_gGOf8,702
61
- pyinfra/facts/pkg.py,sha256=GgRU5x9OWfAfqF-KgJiJz0ndtLKhiRGhtTG4agfunuM,452
62
- pyinfra/facts/pkgin.py,sha256=_rekZJtKLx2TOHd_REJLMDp02typZMpQkZ7sC4FLJSQ,481
63
- pyinfra/facts/postgresql.py,sha256=1xob1BqC6jt4PlUW1jXJkCzTfYvKHiw6cKem0ycerq8,4104
64
- pyinfra/facts/rpm.py,sha256=CdC-r2_cfbt81z3sjAE4I-ne46jI-Of6uyDSvELVJfk,1973
65
- pyinfra/facts/selinux.py,sha256=N0zbJrAtBeRBtxZFUHbYTLQ2L4mRV7_Oj3Cj3OA1Npw,4272
66
- pyinfra/facts/server.py,sha256=gxEW1By_mi9BVZcAQZC5o1Sz0pxQdPVzoQRXV7WxM5w,19794
67
- pyinfra/facts/snap.py,sha256=9PYA73ASi-FgBk_y42lGJyETqEgfcJGm-6EFeKzayhE,1910
68
- pyinfra/facts/systemd.py,sha256=gAw8rLXwXOevs0OLxW0-zACIBC2fcyEtA3Gman4FaOs,3367
69
- pyinfra/facts/sysvinit.py,sha256=PS7yMOrVxclywKjF3BIXmxTBgn2_vpSTQrDeOly_j8Q,1490
70
- pyinfra/facts/upstart.py,sha256=9mqTYsUpDs7gC5Rest2sQS3EohGXAPjEQUINJWELkW0,543
71
- pyinfra/facts/vzctl.py,sha256=AnRl6SZ7HxMGOVl021v0P37pN4tujbwLFuvxUMOCW_M,591
72
- pyinfra/facts/xbps.py,sha256=HBvQ7hvvzC8-Bi952s56Sn4edlOKVITuATpE2sqEPqY,481
73
- pyinfra/facts/yum.py,sha256=h255QEH8VcQTCVdkjwikyk-Pxqzh-dl3Og6a0nMmyVE,827
74
- pyinfra/facts/zypper.py,sha256=O3qoRRh6F6NUP1kEJQ3hE_VJ6C5E8wHPIqZnBthsQcM,766
75
- pyinfra/facts/util/__init__.py,sha256=f7HKu8z9_yFC899ajJ3RFiyivioaZeGfOI6nf9GviCs,521
76
- pyinfra/facts/util/databases.py,sha256=EphGQApzRBXI2nG1FL9h8bozY-o4SgdQgpv9YcnCkxs,730
77
- pyinfra/facts/util/packaging.py,sha256=KF1geTb-C9zs_O1oUfAKpdJCktQJCbvChjeLg6yXzFc,1090
78
- pyinfra/facts/util/win_files.py,sha256=S_IQ5kJD6ZgkEcVHajgh7BIMolLV-1q1ghIcwAS-E1Q,2561
79
- pyinfra/operations/__init__.py,sha256=SOcW337KXIzD_LH-iJJfq14BQcCs5JzwswJ0PIzDgF4,357
80
- pyinfra/operations/apk.py,sha256=WEyNHQ1uU-DgtV4xUbPFCLA5ID4JE22d2gHZvrnJrYY,2049
81
- pyinfra/operations/apt.py,sha256=8wv1otDMW3DAWY-Ox6IRIvPKdLLpQJnb0EN8eFhxXi0,13526
82
- pyinfra/operations/brew.py,sha256=aE-t72NdDHssjvabYxtLfnGlk22OkQhPHrO6BnMgtdI,5040
83
- pyinfra/operations/bsdinit.py,sha256=HtBJERhSiBPaTG0H-m4CG6SY_7iCkl0LtHLGYuNYhVM,1578
84
- pyinfra/operations/cargo.py,sha256=wcEhQEz02e6_WGL6ve_bW1IOrnHQqOGzhyMiMjmm0co,1042
85
- pyinfra/operations/choco.py,sha256=Qr2lg471XiIhMJ4QvUbmRMNCP-3BNE4VbxNaJE-JjzU,1453
86
- pyinfra/operations/dnf.py,sha256=qN9xwLzSFOOJwuUSDhRLTE2TdaNB58HYgtKZMHVn494,5550
87
- pyinfra/operations/files.py,sha256=pQgj40zYB8GM9_JS8v4gh_jO8d3ISVa6DoM072lQrlA,52409
88
- pyinfra/operations/gem.py,sha256=vEGYFniRGrxll8ARNauZQdSPjSHP8-me4UEH1srK-q0,1070
89
- pyinfra/operations/git.py,sha256=mxK2q8Hl3xmo27qz9cRCzVvNxK9UPeG3YFh4cV5fSSM,11543
90
- pyinfra/operations/iptables.py,sha256=KMMWct43Ovx-L2tRY4E1GAyTalk96WOJ4iEJMAjxySU,8856
91
- pyinfra/operations/launchd.py,sha256=i5oeCEekOEQTVlNlayQO057DRXT103H3tWRwp8IRVko,1164
92
- pyinfra/operations/lxd.py,sha256=pcdvmxfG6Bm8m_cuF1wRpmpaUzTq2nTd6iOf4jDRicA,1639
93
- pyinfra/operations/mysql.py,sha256=wtuUi9IhPaehe3qSFf_woEUpPD8mASAIisdIYbnNy3c,19141
94
- pyinfra/operations/npm.py,sha256=PyQJ2DQ_u0jclHNLL21ltUV64VPhC9rriGv5HOc75zY,1404
95
- pyinfra/operations/openrc.py,sha256=eta2j16uC24ZHFBB1CVgV1BdzuvY7S5JjcyGA_iVyYw,1510
96
- pyinfra/operations/pacman.py,sha256=qPtgIzH0151qhmxzoT4rz5xunffNOICcscknCkzLr8o,1672
97
- pyinfra/operations/pip.py,sha256=l3iI1OqGDbOYqO69l-FRgom1NDfVB5HA5hOjnLCTVPI,5377
98
- pyinfra/operations/pkg.py,sha256=sLa3-_YoRMkGNdCovduaZwtAcuADDdaeiKWnIHDiq_k,2222
99
- pyinfra/operations/pkgin.py,sha256=hL_l9kN7Dn68CwPd2efrcJoa2KOToTHLhMpi1P8k3oQ,1930
100
- pyinfra/operations/postgresql.py,sha256=0F7oyf0GXIa4Ex2B187sGdAh2gODZ6mnqCFn-oSDgJU,9162
101
- pyinfra/operations/puppet.py,sha256=EOT4RnYro9K6N_HrPvYHd3bZX8rcAQxPNfLcuzm-LqE,797
102
- pyinfra/operations/python.py,sha256=lQ8lAwy-d_Gg9PVuZVn9-Dl3r5K_XfyUeRKZwekHiuI,1909
103
- pyinfra/operations/selinux.py,sha256=v9Wt1-uLButowbNP8iSEYXSXMd7xAsGp6U9EBXUq5sw,5347
104
- pyinfra/operations/server.py,sha256=evcQgux6fAU5v9z1XUr7ELob2t8HI9n70U5mi0iYm5k,35710
105
- pyinfra/operations/snap.py,sha256=_K-0UdketVIJMe3VlvfvnKGd6NM_3PC-ZzZeeMiGHME,2987
106
- pyinfra/operations/ssh.py,sha256=qrU13gmR-XUcT7l7PvRDfU6WhmfOXd50DZKSZASIyiE,5493
107
- pyinfra/operations/systemd.py,sha256=06xeD7HiNyIcWZ18-GV-3cVdVA-vOx7ij0S9JQv3OEs,3719
108
- pyinfra/operations/sysvinit.py,sha256=cAtfKmGZ0T1HxF0KNTLEU-CrS97n1Vpby58jB3S1Eho,4003
109
- pyinfra/operations/upstart.py,sha256=1lM09OBzH0vWylCHEA_zZPOv_x5W8DVKpnlAd-km7Rc,1908
110
- pyinfra/operations/vzctl.py,sha256=konF-T1KyqZaltRK9BMoUGse8TQb89J2Xbn3kcXh1uM,3010
111
- pyinfra/operations/xbps.py,sha256=vuWwPUqYRIX9kcmg37KjZdtTJUYenG1J8KYFKkIiles,1446
112
- pyinfra/operations/yum.py,sha256=3H6j7gq0ME-u1rBFjV5r3Q4CZErsaAlbLeK6ipuvv8U,5543
113
- pyinfra/operations/zypper.py,sha256=ZZz01tViqVoO185kIJfNj_0H4dnZgRhqFxgCKOH1xXQ,5494
114
- pyinfra/operations/util/__init__.py,sha256=ZAHjeCXtLo0TIOSfZ9h0Sh5IXXRCspfHs3RR1l8tQCE,366
115
- pyinfra/operations/util/files.py,sha256=UwuaGH8_g_glC4QW3LKH7MrzoBpQJ8mk11_g_rk9a8c,3339
116
- pyinfra/operations/util/packaging.py,sha256=fNQaLRtGVrEWFqz2pRAB2nvc1rE7Xd29sXJClzZAChg,8300
117
- pyinfra/operations/util/service.py,sha256=eT_-3r1Lc0aNsNI0p-ocPGjoMfsdcDADqHU82T7GKFE,1031
118
- pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
119
- pyinfra_cli/__main__.py,sha256=8tjq8HUll8P8naFw7pGlygwSz7u9je_MQ-0pqcDlENY,881
120
- pyinfra_cli/commands.py,sha256=eQr3HCuashedJDSxRGdY463FCYHpOmect6I0P_3Z0_U,1761
121
- pyinfra_cli/exceptions.py,sha256=iptx9Zj1od7VgSbOyXs7P8tD4zAZ_fwrQFKPlpPrfS0,4806
122
- pyinfra_cli/inventory.py,sha256=mgj_T_T-lCy6Diyb466doRKIcz4zXLhRJi3ui_VBlXM,9513
123
- pyinfra_cli/inventory_dsl.py,sha256=MY5Qahs6t3yUvc3ughW8gk-iaKbO54doWhZTsI4-mOQ,461
124
- pyinfra_cli/log.py,sha256=7WEGtmf3ncF1BtXL2icUjyxeRKy-7XrCcQ2Hg4GWX5Y,2201
125
- pyinfra_cli/main.py,sha256=zI6sh3aqFIzsnSU9GocmwKo1B8cjH-pYHHV5FA9kKUY,19667
126
- pyinfra_cli/prints.py,sha256=lqNVnGt6Pwr3ooDtbNDeiG0UcKJEUqEXM0rJQlNpIHI,11769
127
- pyinfra_cli/util.py,sha256=7z6xg1GtbD_lB40yLL_m2EwGVTly0Z7V8oeAdQXnKi0,6322
128
- pyinfra_cli/virtualenv.py,sha256=6j9W54JkQLN02SrZZIVwszp0GxlaaDEUWFZjBDHIWNA,2466
129
- tests/test_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
- tests/test_api/test_api.py,sha256=Ig2ebkNACYbHcC4_zRkxS9vj5ZEogoPqGx30ErIKChg,2413
131
- tests/test_api/test_api_arguments.py,sha256=5k7w0_x5cnABEFOk0LQBCt5gU9iTN9lo2XS6MlJTnhQ,1961
132
- tests/test_api/test_api_command.py,sha256=OW0ESMyS5vo38u17DHeCrSIaIkW9gMU5PSkXL7mRrq0,3204
133
- tests/test_api/test_api_config.py,sha256=bf0mDrUie3On6zGC_hJBpv-wvSf3LHBIBzUDvkopEt0,708
134
- tests/test_api/test_api_deploys.py,sha256=diROd47tpFlZAtNfu_E6ijJ4MTzGeRpgRgBSM5kAmjk,4200
135
- tests/test_api/test_api_facts.py,sha256=fUPadZbZ5xaKSF-kmLj7XGwsNiBmfj7Av0gl8fE01Qc,10687
136
- tests/test_api/test_api_host.py,sha256=U_VW2vTl35vR8EdyIGMKr4y0ydsDLbvHSjZDa99CyNE,1119
137
- tests/test_api/test_api_inventory.py,sha256=VLbV0MXdRLOPvTXJF156ne6rAx1cBlFfgq_1S79s4tw,2013
138
- tests/test_api/test_api_operations.py,sha256=z5ChclOsFshU2WEo62uYr9TxCixuUKCU0OJnwBNt4n8,20162
139
- tests/test_api/test_api_util.py,sha256=uHv4oLpoy1_tzOoqFA1zpdvC74SvjitZbxQwp0dmjTs,1716
140
- tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
141
- tests/test_cli/test_cli.py,sha256=nZQH0zK1SOgIr5VxBuuHH68hyzG4lhwyw_Z7EhjPtf4,6045
142
- tests/test_cli/test_cli_deploy.py,sha256=KBnnDsiD21h7t1S2JXpEDpiMxh0AFqwxaEl0z78IE9E,4858
143
- tests/test_cli/test_cli_exceptions.py,sha256=02sjC6rMptuqchgcdjdsVNQbSQYW6HwGutSy6Q6sMs4,3088
144
- tests/test_cli/test_cli_util.py,sha256=-Ehnj0cO-EkF-6KLxcPPcFeuAUMTz-fKITrxhuiYhV4,2562
145
- tests/test_cli/test_context_objects.py,sha256=JiUTwQP7yvcqA47Kq9jtdsB_Z8nxGMZN46d9pR--FYA,2130
146
- tests/test_cli/util.py,sha256=kp_-XsGnTyDgG6IHWorYzl5VD_WLe77dKOH007TDOUE,338
147
- tests/test_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
- tests/test_connectors/test_chroot.py,sha256=QK7YgFPXzHh8y363-tmHvzZ0Ok5PVJWFTDAvwt91eac,5907
149
- tests/test_connectors/test_docker.py,sha256=0EjkfhCHpLCfL4X-AIdMNw5ASaseY0tbRAn7T_TAkMQ,6566
150
- tests/test_connectors/test_dockerssh.py,sha256=MaC9IK1OZDiqoIsuLOZBJnPDglsMoPDoL19LQtXsyCE,9303
151
- tests/test_connectors/test_local.py,sha256=N_FkejDZKu7XLnKeApqfBARYMyxf-hRXCQJrXLHvwRg,7442
152
- tests/test_connectors/test_ssh.py,sha256=5PUG-_6VwHbozgulrjkAtwQekc9UA4EQIpOINcz0R_o,36438
153
- tests/test_connectors/test_sshuserclient.py,sha256=2PQNLPhNL6lBACc6tQuXmPoog-9L6AdDQNrA-rEw1_8,5734
154
- tests/test_connectors/test_terraform.py,sha256=9KPHgBxfy0eni1lGFL6x4ZehG0vJAKjS1E1MO0-6vCw,3807
155
- tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
156
- tests/test_connectors/test_vagrant.py,sha256=A7eHwi2JKjwoKuFQPJZJiCUJ7bdJn9JY2P81Ln3NoIo,3630
157
- pyinfra-3.0b0.dist-info/LICENSE.md,sha256=gwC95tUll0gwB32tHNkTAasN7Sb6vjWzXa305NwClbI,1076
158
- pyinfra-3.0b0.dist-info/METADATA,sha256=Q_w81LJ7bde4NhE8UP2OgkieqFvL_I4FX96e1V2cdTw,8117
159
- pyinfra-3.0b0.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
160
- pyinfra-3.0b0.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
161
- pyinfra-3.0b0.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
162
- pyinfra-3.0b0.dist-info/RECORD,,
@@ -1,23 +0,0 @@
1
- class Host:
2
- name: str
3
- data: dict
4
-
5
- def __init__(self, name, **data) -> None:
6
- self.name = name
7
- self.data = data
8
-
9
-
10
- class Group:
11
- hosts: list[Host]
12
- data: dict
13
-
14
- def __init__(self, *hosts: Host, **data) -> None:
15
- self.hosts = list(hosts)
16
- self.data = data
17
-
18
- def __iter__(self):
19
- for host in self.hosts:
20
- yield host
21
-
22
- def append(self, *hosts: Host) -> None:
23
- self.hosts.extend(hosts)