Я использую ansible для предоставления нескольких экземпляров через aws или другого поставщика облака. Это делается с помощью предоставленного API Python.
Если запустить плейбуки последовательно, все будет работать нормально. Под последовательным я подразумеваю выполнение по одному, переход к следующему только после завершения предыдущего.
Но я хочу выполнить это в асинхронной форме. Я хочу исполнить несколько пьес одновременно. Создание нескольких экземпляров одновременно.
При попытке запустить как минимум 2 или 3 одновременно происходит сбой со следующей ошибкой:
File "/home/usr/proj/ansible.py", line 18, in __init__
self.inventory = InventoryManager(loader=self.loader, sources='/etc/ansible/hosts')
File "/home/usr/proj/venv/lib/python3.6/site-packages/ansible/inventory/manager.py", line 146, in __init__
self.parse_sources(cache=True)
File "/home/usr/proj/venv/lib/python3.6/site-packages/ansible/inventory/manager.py", line 207, in parse_sources
parse = self.parse_source(source, cache=cache)
File "/home/usr/proj/venv/lib/python3.6/site-packages/ansible/inventory/manager.py", line 253, in parse_source
for plugin in self._fetch_inventory_plugins():
File "/home/user/proj/venv/lib/python3.6/site-packages/ansible/inventory/manager.py", line 186, in _fetch_inventory_plugins
plugin = inventory_loader.get(name)
File "/home/usr/proj/venv/lib/python3.6/site-packages/ansible/plugins/loader.py", line 562, in get
obj = getattr(self._module_cache[path], self.class_name)
AttributeError: module 'ansible.plugins.inventory.script' has no attribute 'InventoryModule'
Другая ошибка, которая появляется, - пропуск нескольких плагинов, но не уверенный, связан ли он с предыдущим. Небольшой пример из огромного списка:
[ПРЕДУПРЕЖДЕНИЕ]: Пропуск плагина (/home/usr/venv/lib/python3.6/site-
пакеты / ansible / plugins / connection / buildah.py), как кажется
неверный: модуль
«ansible.plugins.connection./home/usr/venv/lib/python3.6/site-
packages / ansible / plugins / connection / buildah 'не имеет атрибута
'Подключение'
Код из моего приложения, где объявлен инвентарь:
def __init__(self):
self.loader = DataLoader()
self.inventory = InventoryManager(loader=self.loader, sources='/etc/ansible/hosts')
self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
def run_playbook(self, playbook_path: str, playbook_name: str, extra_vars: dict = None, callback=None):
variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
password = open("pass", "r").read()
variable_manager._extra_vars = {"ansible_sudo_pass": password}
variable_manager._extra_vars = {**variable_manager.extra_vars, **extra_vars}
playbook = playbook_path + playbook_name
if not os.path.exists(playbook_path):
print('[INFO] The playbook does not exist')
sys.exit()
# List Of Obligatory Flags To Pass When Running The Playbook
context.CLIARGS = ImmutableDict(listtags=False,
listtasks=False,
listhosts=False,
syntax=False,
start_at_task=None,
connection='ssh',
module_path=None,
forks=100,
remote_user='root',
private_key_file=None,
ssh_common_args='-o StrictHostKeyChecking=no',
ssh_extra_args='-o StrictHostKeyChecking=no',
sftp_extra_args=None,
scp_extra_args=None,
become=True,
become_method='sudo',
become_user='root',
verbosity=5,
check=False,
diff=False,
force_valid_group_names='never')
pbex = PlaybookExecutor(playbooks=[playbook],
inventory=self.inventory,
variable_manager=variable_manager,
loader=self.loader,
passwords={})
pbex._tqm._stdout_callback = callback
return pbex.run()
Попробовал оба источника = 'localhost' и прямой путь к инвентарю хостов
Ansble версия 2.8 и ОС Ubuntu 18
Код, который я использую, просто ненадолго с потоками, вызывающими конечную точку покоя, которая запустит выполнение playbook, означая приведенный выше код:
i = 0
while i <= 2:
x = threading.Thread(target=thread_func, args=(str(i),))
x.start()
i += 1