Показаны сообщения с ярлыком py-configurator. Показать все сообщения
Показаны сообщения с ярлыком py-configurator. Показать все сообщения

среда, 7 мая 2008 г.

py-configurator, scfl - добавки к Cfengine

Для нужд рабочих я написал несколько скриптов:
1. py-configurator - уже описывал и выкладывал;
2. scfl - Sync Config From LDAP - скоро выложу;
3. apt-control - ставит или удаляет пакеты руководствуясь списком из файла.

Это все добавки к Cfengine, хотя если будет время создать py-facter (для выуживания данных из окружения) и py-controller (контроль поцессов, запуск команд шелла и тп), то это будет полностью самостоятельной группой программ. По идее py-configurator и scfl уже связаны в тандем - один выгружает, второй рендерит шаблоны и кладет на место, - но они достаточно легко могут быть использованы по отдельности (достаточно конфигурацию поменять, так как py-configurator по умолчанию лезет в папку, в которую scfl по умолчанию выгружает).

Собственно сайт проекта на Google Code - py-configurator. Со временем туда выложу SCFL и apt-control (надо очистить их от рабочих данных).

Ключевая фишка всего набора - ориентирован он по умолчанию на Kerberos+LDAP окружение, чего, к сожалению, нет ни в одной альтернативе. Иначе я бы не стал изобретать велосипед.

пятница, 2 мая 2008 г.

Скрипт для конфигурации по шаблонам

Кратенький код для конфигурирования машины по шаблонам файлов. Действует так - натравливаете его на каталог с шаблонами, он строит в указаной вами папке то самое дерево, только с отрендеренными шаблонами. По первому же импорту знающие люди поймут какой должен быть синтаксис : ) Ну а для людей не от мира Django будут примеры. Код:


#! /usr/bin/python

from jinja import Environment, FileSystemLoader
from ConfigParser import SafeConfigParser
import os


# pc_cfg = py-configurator
pc_cfg = SafeConfigParser()
pc_cfg.read('/etc/py-configurator/py-configurator.cfg')
pc_config = dict(pc_cfg.items('main'))

base_path = pc_cfg.get('main','templates').rstrip('/')
target_path = pc_cfg.get('main','target').rstrip('/')
if not target_path:
target_path='/'
machine_cfg = pc_cfg.get('main','machine_cfg')
print 'Configuration:',pc_config.items()

ws_cfg = SafeConfigParser()
ws_cfg.read(machine_cfg)
ws_config = dict(ws_cfg.items('main'))

base_len = len(base_path)+1
env = Environment(loader=FileSystemLoader(base_path))

for root, dirs, files in os.walk(base_path, topdown=False):
for name in files:
na_root = root[base_len:]+'/' if root!=base_path else ''
print "Work on file:",name,"Root:",root,"Short root",na_root
tmpl_file=na_root+name
try:
os.lstat(os.path.join(target_path,na_root))
except:
os.mkdir(os.path.join(target_path,na_root))
tmpl = env.get_template(tmpl_file)

tmpl_vars={'name':tmpl_file}
tmpl_vars.update(os.environ)
tmpl_vars.update(ws_config)

open(os.path.join(target_path,tmpl_file),'w').write(tmpl.render(**tmpl_vars))



Пример конфига:

[main]
templates = /etc/py-configurator/templates/
target = /etc
machine_cfg = /etc/machine.cfg

Переменные берет из /etc/machine.cfg, например из такого:

[main]
ws_name = ws3
ws_num = 3
domain = msk5
region_addr = 24
dep_addr = 55

По сути сварганить бы что то вроде facter из puppet, но еще один велосипед, даже не знаю стоит ли.
Обещаный пример (/etc/hosts):

127.0.0.1 localhost
10.{{ region_addr }}.{{ dep_addr }}.{{ ws_num }} {{ ws_name }}.{{ domain }}.realm.tld {{ ws_name }}
10.{{ region_addr }}.{{ dep_addr }}.1 kdc.{{ domain }}.realm.tld

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Подробнее о синтаксисе шаблонов (а он богат возможностями) тут.
Собственно вся затея с etc-шаблонятором родилась от любви к шаблонам Django, ну и слегка требовалась утилита шаблонной настройки.