Skip to content

Commit aa5fd40

Browse files
authored
Merge pull request #560 from nvgoldin/sdk_ansible
sdk: added ansible inventory methods
2 parents ed2d079 + e06f502 commit aa5fd40

File tree

6 files changed

+102
-2
lines changed

6 files changed

+102
-2
lines changed

automation/check-patch.packages

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
ansible
12
bats
23
dnf
34
dnf-command(builddep)

automation/check-patch.packages.el7

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
ansible
12
bats
23
git
34
libffi-devel

lago/plugins/vm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def extract_paths(self, paths, ignore_nopath):
235235
:exc:`~lago.plugins.vm.ExtractPathError`: on all other failures.
236236
"""
237237
if self.vm.alive() and self.vm.ssh_reachable(
238-
tries=1, propagate_fail=False
238+
tries=5, propagate_fail=False
239239
):
240240
self._extract_paths_scp(paths=paths, ignore_nopath=ignore_nopath)
241241
else:

lago/sdk.py

+60
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import print_function
22
from lago import cmd
33
from lago.config import config as lago_config
4+
from lago.lago_ansible import LagoAnsible
45
from lago import workdir as lago_workdir
56
from lago.log_utils import get_default_log_formatter
67
from sdk_utils import SDKWrapper, setup_sdk_logging
@@ -136,3 +137,62 @@ def destroy(self):
136137
entirely the Lago working directory.
137138
"""
138139
self._workdir.destroy()
140+
141+
def ansible_inventory_temp_file(
142+
self, keys=['vm-type', 'groups', 'vm-provider']
143+
):
144+
"""
145+
Context manager which returns Ansible inventory written on a tempfile.
146+
This is the same as :func:`~ansible_inventory`, only the inventory file
147+
is written to a tempfile.
148+
149+
Args:
150+
keys (list of str): Path to the keys that will be used to
151+
create groups.
152+
153+
Yields:
154+
tempfile.NamedTemporaryFile: Temp file containing the inventory
155+
"""
156+
lansible = LagoAnsible(self._prefix)
157+
return lansible.get_inventory_temp_file(keys=keys)
158+
159+
def ansible_inventory(
160+
self,
161+
keys=['vm-type', 'groups', 'vm-provider'],
162+
):
163+
"""
164+
Get an Ansible inventory as a string, ``keys`` should be list on which
165+
to group the hosts by. You can use any key defined in LagoInitFile.
166+
167+
Examples of possible `keys`:
168+
169+
`keys=['disks/0/metadata/arch']`, would group the hosts by the
170+
architecture.
171+
172+
`keys=['/disks/0/metadata/distro', 'disks/0/metadata/arch']`,
173+
would create groups by architecture and also by distro.
174+
175+
`keys=['groups']` - would group hosts by the groups defined for
176+
each VM in the LagoInitFile, i.e.:
177+
178+
domains:
179+
180+
vm-01:
181+
...
182+
groups: web-server
183+
..
184+
vm-02:
185+
..
186+
groups: db-server
187+
188+
189+
Args:
190+
keys (list of str): Path to the keys that will be used to
191+
create groups.
192+
193+
Returns:
194+
str: INI-like Ansible inventory
195+
"""
196+
197+
lansible = LagoAnsible(self._prefix)
198+
return lansible.get_inventory_str(keys=keys)

lago/ssh.py

+2
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@ def get_ssh_client(
366366
host_name,
367367
err,
368368
)
369+
except EOFError as err:
370+
LOGGER.debug('EOFError connecting to %s: %s', host_name, err)
369371
ssh_tries -= 1
370372
time.sleep(1)
371373
else:

tests/functional-sdk/test_sdk_sanity.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
import uuid
99
from jinja2 import Environment, BaseLoader
1010
from lago import sdk
11+
from lago.utils import run_command
1112

1213

1314
@pytest.fixture(scope='module')
1415
def init_str(images):
1516
init_template = textwrap.dedent(
1617
"""
1718
domains:
18-
{% for vm_name, template in images.iteritems() %}
19+
{% for vm_name, template in images.viewitems() %}
1920
{{ vm_name }}:
2021
memory: 1024
2122
nics:
@@ -33,6 +34,7 @@ def init_str(images):
3334
- /etc/resolv.conf
3435
- /etc/sysconfig
3536
- /etc/NetworkManager
37+
groups: group{{ loop.index % 2 }}
3638
{% endfor %}
3739
3840
nets:
@@ -205,3 +207,37 @@ def test_load_env_up(env, vms, tmp_workdir):
205207
assert vm.state() == 'running'
206208
for vm in loaded_env.get_vms().values():
207209
assert vm.ssh_reachable(tries=200)
210+
211+
212+
@pytest.mark.check_merged
213+
def test_ansible_inventory(monkeypatch, env, test_results, vms):
214+
215+
# ansible returns the results in a bulk to stdout. Ideally we would test
216+
# forthe hostname of each machine, but that is broken on debian.
217+
# Instead, we let it compute something and count the unique occurences.
218+
219+
cmd = 'echo __abcd$(( 24 + 12 ))efgh___'
220+
expected = '__abcd36efgh__'
221+
results = []
222+
223+
with env.ansible_inventory_temp_file(keys=['groups']) as inv:
224+
for group in ['group0', 'group1']:
225+
logfile = os.path.join(
226+
test_results, 'ansible-{0}.log'.format(group)
227+
)
228+
monkeypatch.setenv('ANSIBLE_LOG_PATH', logfile)
229+
monkeypatch.setenv('ANSIBLE_HOST_KEY_CHECKING', 'False')
230+
res = run_command(
231+
[
232+
'ansible', 'groups={0}'.format(group), '-v', '-u', 'root',
233+
'-i', inv.name, '-m', 'raw', '-a', cmd
234+
]
235+
)
236+
237+
assert res.code == 0
238+
assert res.out is not None
239+
results.append(res)
240+
241+
occurences = sum([result.out.count(expected) for result in results])
242+
243+
assert occurences == len(vms.keys())

0 commit comments

Comments
 (0)