Comments 6
Мне кажется, в результате выполнения
мы получим строку с запятой в конце, что неприемлемо для многих приложений. У Вас есть рецепт, как этого избежать?
zk.connect={% for host in groups['zk_nodes'] %}{{ hostvars[host]['ansible_eth0']['ipv4']['address'] }}:{{ zk_port }}, {% endfor %}
мы получим строку с запятой в конце, что неприемлемо для многих приложений. У Вас есть рецепт, как этого избежать?
Замечание совершенно верное, в конце действительно будет запятая. На момент написания статьи средства для избавления от этой запятой у меня не было, но и необходимости от неё избавляться — тоже: приложение на Java эту запятую благополучно игнорирует.
Однако беглый поиск подсказал, что достаточно заключить разделяющую запятую вот в такую конструкцию:
Применительно к строчке из статьи получим вот что:
Или можно использовать второй вариант, приведённый в комментариях на SO по ссылке выше, но лично я в Jinja2 пока не настолько силён, чтобы уверенно написать, как правильно две подстановочные переменные со статическим символом (",") сцепить в список через фильтр «join» :-)
Однако беглый поиск подсказал, что достаточно заключить разделяющую запятую вот в такую конструкцию:
{% if not loop.last %}
,
{% endif %}
Применительно к строчке из статьи получим вот что:
zk.connect={% for host in groups['zk_nodes'] %}{{ hostvars[host]['ansible_eth0']['ipv4']['address'] }}:{{ zk_port }}{% if not loop.last %},{% endif %} {% endfor %}
Или можно использовать второй вариант, приведённый в комментариях на SO по ссылке выше, но лично я в Jinja2 пока не настолько силён, чтобы уверенно написать, как правильно две подстановочные переменные со статическим символом (",") сцепить в список через фильтр «join» :-)
В моем случае инвенторий был статический, и выкрутился написанием плагина на питоне:
# vars_plugins/zookeeper_vars.py
from ansible import errors
from ansible import utils
import ansible.constants as C
from ansible.callbacks import display
class VarsModule(object):
def __init__(self, inventory):
self.inventory = inventory
self.group_cache = {}
self.known_zoo_ids = []
def run(self, host, vault_password=None):
inventory = self.inventory
group = inventory.get_group('zookeeper')
zk_addr = []
if group is not None:
hosts = group.get_hosts()
for idx, host in enumerate(hosts):
host_vars = host.get_variables()
addr = host_vars.get('node_private_ip')
if addr is None:
addr = host_vars.get('ansible_ssh_host', host.name)
zk_port = host_vars.get('zookeeper_port', '2181')
zk_addr.append({'host': addr, 'port': zk_port})
node_zoo_id = host_vars.get('node_zoo_id', idx + 1)
self.assign_zoo_id(host, node_zoo_id)
result = {}
result['zookeepers'] = zk_addr
result['zookeepers_list'] = ','.join([':'.join([i['host'], i['port']]) for i in zk_addr])
return result
def assign_zoo_id(self, host, zoo_id):
if zoo_id not in self.known_zoo_ids:
host.set_variable('node_zoo_id', zoo_id)
self.known_zoo_ids.append(zoo_id)
else:
display("warning: node_zoo_id of %s is already used!" % zoo_id, color='purple')
new_zoo_id = int(zoo_id) + 1
if new_zoo_id > 255:
raise errors.AnsibleError("zoo_id (%s) for host %s is over 255!" % (new_zoo_id, host.name))
self.assign_zoo_id(host, str(new_zoo_id))
цитата - скрытый код на Python
node_zoo_id = host_vars.get('node_zoo_id', idx + 1)
Правильно ли я понимаю, что в таком варианте требуется прописывать переменную node_zoo_id для каждого хоста вручную?
Сразу скажу, я не очень разбираюсь во внутренностях Zookeeper.
По идее в кластере zookeeper-ам надо вписывать в конфиг уникальное значение zoo_id (0-255).
Плагин берет указанное значение (node_zoo_id), либо в случае если оно не указано — номер хоста из группы «zookeeper».
По идее в кластере zookeeper-ам надо вписывать в конфиг уникальное значение zoo_id (0-255).
Плагин берет указанное значение (node_zoo_id), либо в случае если оно не указано — номер хоста из группы «zookeeper».
Нашёл красивый вариант решения вопроса с нумерацией хостов на GitHub
Но он настолько изящен, что я не могу удержаться от того, чтобы привести его прямо здесь:
Но он настолько изящен, что я не могу удержаться от того, чтобы привести его прямо здесь:
templates/myid.j2
Здесь zk-nodes — это имя группы узлов, к которым применяется данный шаблон.
{% for server in groups['zk-nodes'] %}
{% if server == inventory_hostname %}
{{ loop.index }}
{% endif %}
{% endfor %}
Sign up to leave a comment.
Работа с Ansible — задачи с несколькими неизвестными