Puppet/Запуск puppetry (пример с libvirt): различия между версиями

Материал из ALT Linux Wiki
 
(не показано 38 промежуточных версий 3 участников)
Строка 4: Строка 4:
[[category:виртуализация]]
[[category:виртуализация]]
[[Категория:Тестирование]]
[[Категория:Тестирование]]
[[category: Puppet]]


{{stub}}
{{stub}}
Строка 11: Строка 12:
:* Образы для таких виртуальных машин.
:* Образы для таких виртуальных машин.


Помимо прочего на этой странице получилось своеобразное руководство к некоторым командам {{cmd|virt-*}} (для {{prg|libvirt}}). Приветствуются исправления и дополнения к этому тексту (и пакетам и образам)! Нерешённые проблемы и задачи сейчас:
Помимо прочего на этой странице получилось своеобразное руководство к некоторым командам {{cmd|virt-*}} (для {{prg|libvirt}}). Приветствуются исправления и дополнения к этому тексту (и пакетам и образам)!


# Выполнение манифеста на другой ноде. -- [[#Тестирование puppet]]
==Нерешённые проблемы и задачи==
Перечень нерешённых сейчас проблем и задач, решение которых нужно для успешного запуска ALT puppetry (кем угодно из сообщества по этой инструкции):
 
# {{есть|1=[https://www.altlinux.org/index.php?title=%D0%97%D0%B0%D0%BF%D1%83%D1%81%D0%BA_puppet_theatre&diff=37991&oldid=37989 описано как]}} Выполнение манифеста на другой ноде. -- [[#Тестирование puppet]]
# Проверка и адаптация к ALT базовых средств, модулей puppet (пакетный менеджер в первую очередь, задействованный при работе некоторых других модулей). -- task #175947 test-only sisyphus ruby-facter.git=2.0.1-alt2 puppet.git=4.8.1-alt1
# Проверка и адаптация к ALT базовых средств, модулей puppet (пакетный менеджер в первую очередь, задействованный при работе некоторых других модулей). -- task #175947 test-only sisyphus ruby-facter.git=2.0.1-alt2 puppet.git=4.8.1-alt1
# Подготовка образа для тестирования puppet.
# Подготовка образа для тестирования puppet.
# Проверка и адаптация к ALT прочих модулей.


(Об оформлении.
И перечень задач, ради совместного решения которых пригодится ALT puppetry (к чему готовиться?):
Изменяемые (по вкусу каждого пользователя) параметры в примерах я старался выделять жирным, чтобы можно было их легко отличить от определённых не нами штук с жёстко заданными именами.)
 
* Проверка и адаптация к ALT прочих модулей.
* Как эти наработки по адаптации интегрировать в экосистему puppet (upstream) и в ALT Sisyphus? Как гарантировать консистентность того, что записано в исходниках puppet и его модулей, и пакетов ALT Sisyphus?
 
Такой вопрос касается:
 
# консистентности внутри ALT Sisyphus:<br />-- Все изменения для puppet и управляемых пакетов общего назначения полностью под контролем ALT, но как формализовать зависимости, проверки?
# ситуации когда к людям попадает upstream-ный puppet-мастер (крутящийся на какой угодно ОС), но часть подчинённых нод с ALT:<br />-- А может ли подчинённая нода хранить некоторые знания о своих особенностях (особенностях ALT) и влиять на выполняемые по заказу мастера действия, когда мастер не имеет информации обо всех особенностях ALT? Это бы позволило перенести достижения разработки в ALT Sisyphus на такой случай.
# предыдущей ситуации, суженной до конкретного специализированного дистрибутива с puppet-мастером и некоторым набором пакетов, рассчитанного на то, чтобы управлять подчинёнными нодами в т.ч. на ALT (с использованием пакетов из этого подготовленного набора).<br />-- Ввиду уже сформулированных общих вопросов про разработку и проверку внутри ALT Sisyphus и интеграцию с upstream-ным puppet-ом остаётся вопрос о том, как упростить создание (или адаптацию для ALT) таких дистрибутивов.
 
(Дополнительно к решению всех озвученных проблем в лоб, есть мысли обратиться к [[distrodb]]/[[distromap]], чтобы "переводить" использование пакетов других дистрибутивов в пакеты ALT для стыковки с puppet-ом ALT-овых нод.)
 
==Оформление инструкций в этом руководстве==
 
Изменяемые (по вкусу каждого пользователя) параметры в примерах я старался выделять жирным, чтобы можно было их легко отличить от определённых не нами штук с жёстко заданными именами.




Строка 27: Строка 44:


Такая сеть таким образом (как нам нужно) будет использоваться, когда машина будет создаваться {{cmd|1=virt-install --network network='''puppettheatre'''}} (а не {{cmd|1=--network bridge='''BRIDGE'''}}; см. man virt-install).
Такая сеть таким образом (как нам нужно) будет использоваться, когда машина будет создаваться {{cmd|1=virt-install --network network='''puppettheatre'''}} (а не {{cmd|1=--network bridge='''BRIDGE'''}}; см. man virt-install).
('''BUG:''' Чтобы запустить такую сеть, как мы делаем, нужен {{path|/dev/net/tun}}. Его может не быть в системе без systemd ([https://bugzilla.altlinux.org/show_bug.cgi?id=31718#c27 altbug 31718#c27]). Появлется после загрузки модуля: {{cmd|modprobe tun}} или описанным действием, которого сейчас не хватает: {{cmd|1=/sbin/systemd-tmpfiles --prefix=/dev --create --boot}}.)


===(удобно) КОМАНДОЙ===
===(удобно) КОМАНДОЙ===
Строка 53: Строка 72:


==Создание машины с ALTовым puppet-мастером==
==Создание машины с ALTовым puppet-мастером==
('''BUG''' {{altbug|33801}}: требуется установить qemu; по зависимостям {{pkg|libvirt-daemon-driver-qemu}} оно не вытягивается.)


===(удобно) КОМАНДОЙ===
===(удобно) КОМАНДОЙ===
Строка 58: Строка 79:


===(неудобно) ВРУЧНУЮ через GUI инсталлятора alterator через virt-viewer===
===(неудобно) ВРУЧНУЮ через GUI инсталлятора alterator через virt-viewer===
(Использовался {{pkg|virt-viewer-5.0-alt1}}.)
(Использовался {{pkg|virt-viewer-5.0-alt1}}, {{pkg|virt-install-1.4.0-alt1}}, {{pkg|libvirt-1.3.2-alt1}}, а также более поздние версии.)


Пример: <pre>
Пример: <pre>
virt-install --virt-type kvm \
virt-install --virt-type kvm \
   --name imz-puppet-master-ALT0 \
   --name imz-puppetry0-master-ALT \
   --memory 1024 --disk size=10 \
   --memory 1024 --disk size=10 \
   --cdrom /space/iso/nightly/tested/regular-lxde-latest-x86_64.iso \
   --cdrom /space/iso/nightly/tested/regular-lxde-latest-x86_64.iso \
   --network network=puppettheatre \
   --network network=puppettheatre \
   --os-variant altlinux7
   --os-variant altlinux7.0
</pre>
</pre>


* {{cmd|1=--name '''imz-puppet-master-ALT0'''}} -- какое-нибудь имя;
* {{cmd|1=--name '''imz-puppetry0-master-ALT'''}} -- какое-нибудь имя;
* {{path|regular-lxde-latest-x86_64.iso}} выбран как небольшой образ для инсталляции системы с {{prg|systemd}} (сначала грузится LiveCD, что пока не важно, хотя есть планы тестировать puppet-мастер прямо с LiveCD);
* {{path|regular-lxde-latest-x86_64.iso}} выбран как небольшой образ для инсталляции системы с {{prg|systemd}} (сначала грузится LiveCD, что пока не важно, хотя есть планы тестировать puppet-мастер прямо с LiveCD); до исправления {{altbug|33334}} рекомендуется использовать рабочий архивный образ {{path|/space/iso/nightly/archive/regular-tde-20170111-x86_64.iso}}, а после настройки доступа по ssh сделать {{cmd|apt-get dist-upgrade}};
* {{cmd|1=--network network='''...'''}} прокомментирован выше в [[#Создание сети]];
* {{cmd|1=--network network='''...'''}} прокомментирован выше в [[#Создание сети]];
* {{cmd|1=--os-variant altlinux7}} просто выбран как самый старший из известных ему ALTовых.
* {{cmd|1=--os-variant altlinux7.0}} просто выбран как самый свежий из известных ему ALTовых. (В man-странице из {{pkg|virt-install-1.4.0-alt1}} и позже сказано посмотреть варианты командой {{cmd|osinfo-query os}}; оно из пакета {{pkg|libosinfo-1.0.0-alt1}}; раньше было немного по-другому.)


====Запуск машины====
====Запуск машины====
Строка 115: Строка 136:
* Т.к. в сети есть NAT для связи со внешним миром, мы можем использовать наш '''реальный DNS''' из внешнего мира. (Был прописан вручную, конечно.)
* Т.к. в сети есть NAT для связи со внешним миром, мы можем использовать наш '''реальный DNS''' из внешнего мира. (Был прописан вручную, конечно.)


Напоследок включим sshd для входа по сети (правда, только с хочт-системы, потому что IP нашей виртуальной машины за NAT.)
Удалим мешающееся для настройки сети:


====Добавочные костыли в конфигурации====
apt-get remove NetworkManager
 
Напоследок включим sshd для входа по сети (правда, только с хост-системы, потому что IP нашей виртуальной машины за NAT.)
 
====Общие добавочные костыли и плюшки в конфигурации====
Добавочные "костыли" в конфигурации этой создаваемой ВРУЧНУЮ машины делаем ради удобства/быстроты получения уже чуточку сконфигурированных подчинённых машин как клонов.
Добавочные "костыли" в конфигурации этой создаваемой ВРУЧНУЮ машины делаем ради удобства/быстроты получения уже чуточку сконфигурированных подчинённых машин как клонов.


TODO: Планируется реализовать эту добавочную конфигурацию более прозрачными, чем костыли, способами: сетевыми сервисами; внести всё потребовавшееся и описанное на этой странице в запланированный нами профиль для {{pkg|[[mkimage]]}} (образ VM/LiveCD для тестирования puppet в сети-песочнице -- "{{path|puppettheatre.img/.iso}}").
TODO: Планируется реализовать эту добавочную конфигурацию более прозрачными, чем костыли, способами: сетевыми сервисами; внести всё потребовавшееся и описанное на этой странице в запланированный нами профиль для {{pkg|[[mkimage]]}} (образ VM/LiveCD для тестирования puppet в сети-песочнице -- "{{path|puppetry.img/.iso}}").
 
* Скорее всего нам будет удобно ходить на эти машины по ssh, так что убедимся что {{prg|sshd}} включен и настроен. (Остальные действия можно будет делать по ssh.)


* Пусть клоны видят свой puppet-мастер по имени на фиксированном IP-адресе (этой машины):
* Пусть клоны видят свой puppet-мастер по имени на фиксированном IP-адресе (этой машины):


    echo ''''192.168.121.2''' puppet' >>/etc/hosts
echo ''''192.168.121.2''' puppet' >>/etc/hosts


* Можно поставить какие-то любимые пакеты сейчас, перед тем, как эта машина будет использована как исходник для клонирования; например:
* Можно поставить какие-то любимые пакеты сейчас, перед тем, как эта машина будет использована как исходник для клонирования; например:


    apt-get update; apt-get install '''emacs25-X11-gtk3'''
apt-get update; apt-get install '''emacs25-X11-gtk3 emacs-misc-modes emacs-prog-modes slocate apt-printchanges telnet lsof moreutils'''
systemctl enable crond
updatedb
 
* Для удобства положим технический SSH-ключ:
 
[root@vb ~]# rsync -avP ~/.ssh/id_rsa.pub user@192.168.121.2:.ssh/hypervisor-id_rsa.pub
[root@vb ~]# ssh user@192.168.121.2 'cat .ssh/hypervisor-id_rsa.pub >>.ssh/authorized_keys'
[root@vb ~]# ssh user@192.168.121.2 -t su -c "'cat ~user/.ssh/hypervisor-id_rsa.pub >>/root/.ssh/authorized_keys'"


====Используем машину как исходник для клонирования====
====Используем машину как исходник для клонирования====
Строка 135: Строка 170:
Думаю, удобно будет её сохранить в первоначальном виде и не трогать эту копию. (А копию уже использовать как исходник для всяких ALTовых нод.)
Думаю, удобно будет её сохранить в первоначальном виде и не трогать эту копию. (А копию уже использовать как исходник для всяких ALTовых нод.)


    ssh '''user@192.168.121.2''' -t su -c /sbin/poweroff; ping '''192.168.121.2'''
ssh '''user@192.168.121.2''' -t su -c /sbin/poweroff; ping '''192.168.121.2'''
    virt-clone --original '''imz-puppet-master-ALT0''' --auto-clone
virt-clone --original '''imz-puppetry0-master-ALT''' --auto-clone


Заметьте, что сеть будет использоваться та же самая -- как нам и нужно (для общения создаваемых нод между собой).<ref>Посмотрите, что получилось с клоном:<pre>
Заметьте, что сеть будет использоваться та же самая -- как нам и нужно (для общения создаваемых нод между собой).<ref>Посмотрите, что получилось с клоном:<pre>
[root@vb ~]# diff -du <(virsh dumpxml imz-puppet-master-ALT0)  <(virsh dumpxml imz-puppet-master-ALT0-clone)
[root@vb ~]# diff -du <(virsh dumpxml imz-puppetry0-master-ALT)  <(virsh dumpxml imz-puppetry0-master-ALT-clone)
--- /dev/fd/63 2017-01-24 14:04:17.089573354 +0300
--- /dev/fd/63 2017-01-24 14:04:17.089573354 +0300
+++ /dev/fd/62 2017-01-24 14:04:17.089573354 +0300
+++ /dev/fd/62 2017-01-24 14:04:17.089573354 +0300
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
  <domain type='kvm'>
  <domain type='kvm'>
-  <name>imz-puppet-master-ALT0</name>
-  <name>imz-puppetry0-master-ALT</name>
-  <uuid>887ffdb5-3222-4717-8b13-820c1ba543ad</uuid>
-  <uuid>887ffdb5-3222-4717-8b13-820c1ba543ad</uuid>
+  <name>imz-puppet-master-ALT0-clone</name>
+  <name>imz-puppetry0-master-ALT-clone</name>
+  <uuid>463057db-4470-4b6a-b44b-6f19d8040793</uuid>
+  <uuid>463057db-4470-4b6a-b44b-6f19d8040793</uuid>
   <memory unit='KiB'>1048576</memory>
   <memory unit='KiB'>1048576</memory>
Строка 155: Строка 190:
     <disk type='file' device='disk'>
     <disk type='file' device='disk'>
       <driver name='qemu' type='qcow2'/>
       <driver name='qemu' type='qcow2'/>
-      <source file='/var/lib/libvirt/images/imz-puppet-master-ALT0.qcow2'/>
-      <source file='/var/lib/libvirt/images/imz-puppetry0-master-ALT.qcow2'/>
+      <source file='/var/lib/libvirt/images/imz-puppet-master-ALT0-clone.qcow2'/>
+      <source file='/var/lib/libvirt/images/imz-puppetry0-master-ALT-clone.qcow2'/>
       <target dev='vda' bus='virtio'/>
       <target dev='vda' bus='virtio'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
Строка 171: Строка 206:
[root@vb ~]#  
[root@vb ~]#  
</pre></ref>
</pre></ref>
Для удобства будущей перенастройки новых клонов этого клона без выключения других машин (без коллизии с IP-адресом работающего puppet-мастера) я бы в клоне сразу поменял IP-адрес на некий выделенный временный, [[#(неудобно) ВРУЧНУЮ: склонируем что-то; сконфигурируем|как это делается потом для всех рабочих подчинённых нод]], например, '''<code>192.168.121.16</code>''':
[root@vb ~]# virsh start '''imz-puppetry0-master-ALT'''-clone
[root@vb ~]# ssh root@'''192.168.121.2'''
[root@puppet ~]# emacs /etc/net/ifaces/eth0/ipv4address
[root@puppet ~]# cat /etc/net/ifaces/eth0/ipv4address
'''192.168.121.16/24'''
[root@puppet ~]# poweroff


==Создание подчинённой машины с ALTом==
==Создание подчинённой машины с ALTом==
Строка 179: Строка 223:
Для простоты склонируем созданную ВРУЧНУЮ машину; у нас уже [[#Используем машину как исходник для клонирования|заготовлена]] копия; её склонируем и сконфигурируем потом:
Для простоты склонируем созданную ВРУЧНУЮ машину; у нас уже [[#Используем машину как исходник для клонирования|заготовлена]] копия; её склонируем и сконфигурируем потом:


    virt-clone --original '''imz-puppet-master-ALT0-clone''' --name '''imz-puppet-slave-ALT0''' --auto-clone
virt-clone --original '''imz-puppetry0-master-ALT-clone''' --name '''imz-puppetry0-slave0-ALT''' --auto-clone


Сконфигурируем сеть (пока исходник клона опущен), зайдя по ssh по старому IP-адресу:
Сконфигурируем сеть (пока исходник клона опущен), зайдя по ssh по старому IP-адресу:


    [root@vb ~]# virsh start '''imz-puppet-slave-ALT0'''; ping '''192.168.121.2'''
[root@vb ~]# virsh start '''imz-puppetry0-slave0-ALT'''; ping '''192.168.121.16'''
    [root@vb ~]# ssh '''user@192.168.121.2'''
[root@vb ~]# ssh '''user@192.168.121.16'''
    [user@puppet ~]$ su -
[user@puppet ~]$ su -
    # emacs /etc/net/ifaces/eth0/ipv4address /etc/sysconfig/network  
# emacs /etc/net/ifaces/eth0/ipv4address /etc/sysconfig/network  


Назначим новый IP-адрес и имя, убдимся, что по имени <code>puppet</code> мы можем обратиться к puppet-мастеру:<pre>
Назначим новый IP-адрес и имя, убдимся, что по имени <code>puppet</code> мы можем обратиться к puppet-мастеру:<pre>
Строка 211: Строка 255:
</pre>
</pre>


Можно перезагружать: {{cmd|ssh user@192.168.121.2 -t su -c /sbin/reboot; ping 192.168.121.3}}
Можно перезагружать: {{cmd|ssh user@192.168.121.16 -t su -c /sbin/reboot; ping 192.168.121.3}}


==Запуск машин==
==Запуск машин==
Примеры:


{{cmd|virsh start '''imz-puppet-master-ALT0'''}}
virsh start '''imz-puppetry0-master-ALT'''; ping '''192.168.121.2'''
virsh start '''imz-puppetry0-slave0-ALT'''; ping '''192.168.121.3'''


Работа с машинами происходит подключением через {{prg|virt-manager}} или по {{prg|ssh}} с хост-системы-гипервизора.
Работа с машинами происходит подключением через {{prg|virt-manager}} или по {{prg|ssh}} с хост-системы-гипервизора.
===Остановка машин===
Примеры остановки по-хорошему:
ssh root@'''192.168.121.2''' poweroff
ssh user@'''192.168.121.2''' -t su -c /sbin/poweroff
Остановка грубо (подсмотрено в {{prg|virt-delete}} из [[#Удаление машин]]):
virsh destroy '''imz-puppetry0-master-ALT'''
(это именно аналог выключения питания, а не удаление образов).


==Удаление машин==
==Удаление машин==
Строка 227: Строка 285:
===Предварительные штуки: пакеты, сервисы===
===Предварительные штуки: пакеты, сервисы===


    [root@puppet ~]# apt-get install puppet-server  
[root@puppet ~]# apt-get install puppet-server  
    [root@slave0 ~]# apt-get install puppet
[root@slave0 ~]# apt-get install puppet


    [root@puppet ~]# service puppetmaster start
[root@puppet ~]# service puppetmaster start
    [root@puppet ~]# systemctl enable puppetmaster
[root@puppet ~]# systemctl enable puppetmaster


Демона агента на подчинённой ноде пока апускать не будем, потому что тестировать интереснее однократным вызовом с отладочной информацией (как будет ниже в примере: {{cmd|puppet agent --test --debug}}):
Демона агента на подчинённой ноде пока запускать не будем, потому что тестировать интереснее однократным вызовом с отладочной информацией (как будет ниже в примере: {{cmd|puppet agent --test --debug}}):


    [root@slave0 ~]# #service puppet start
[root@slave0 ~]# #service puppet start


===Создание и выполнение тестовых манифестов===
===Создание и выполнение тестовых манифестов===
Строка 243: Строка 301:
  [root@puppet puppet]# mkdir -p /etc/puppet/environments/production/manifests
  [root@puppet puppet]# mkdir -p /etc/puppet/environments/production/manifests


Используем [http://www.thegeekstuff.com/2015/07/puppet-configuration-examples простейший пример манифеста]:<pre>
В Puppet3 нужно отредактировать файл {{path|/etc/puppet/puppet.conf}}, добавив в секцию <code>Main</code> следующий код:
[root@slave0 ~]# l /tmp/puppet-testfile
ls: cannot access /tmp/puppet-testfile: No such file or directory
environmentpath = $confdir/environments
[root@puppet puppet]# cat >/etc/puppet/environments/production/manifests/test.pp
 
Затем нужно перезапустить puppetmaster.
 
Попробуем [http://www.thegeekstuff.com/2015/07/puppet-configuration-examples простейший пример манифеста] (эта ссылка просто на пример исходного кода для puppet; команды для тестирования все перечислены и на нашей странице; нет необходимости пробовать, например, {{cmd|puppet apply}}). Этот пример манифеста создаст {{path|/tmp/puppet-testfile}}. В начале работы его нет:
 
[root@slave0 ~]# l /tmp/puppet-testfile
ls: cannot access /tmp/puppet-testfile: No such file or directory
 
Сам манифест:<pre>
[root@puppet puppet]# cat >/etc/puppet/environments/production/manifests/test0.pp
file { "/tmp/puppet-testfile":
file { "/tmp/puppet-testfile":
         ensure => "present",
         ensure => "present",
Строка 257: Строка 324:
</pre>
</pre>


Выполнить его на slave0 почему-то у меня пока не получилось, но на том же хосте (puppet), где мастер, получается. Перезапускать puppetmaster не нужно, чтобы читался новый манифест. Имя {{path|.pp}}-файла не важно. Одноразовое тестирование выполнения с отладочной информацией делается командой:
Выполнить его на slave0, возможно, не получится с первого раза (см. решение про подпись ниже), но попробовать запустить агент можно всё равно сразу, и пробовать сколько угодно раз. Перезапускать puppetmaster не нужно, чтобы читался новый манифест. Имя {{path|.pp}}-файла не важно. Одноразовое тестирование выполнения с отладочной информацией делается командой:


    puppet agent --test --debug
puppet agent --test --debug
    l /tmp/pup*
l /tmp/pup*


({{cmd|service puppet start}} собственно и запускает такого агента, но не в одноразовом режиме; мы пока так демона-агента не запускаем, потому что неинтересно для тестирования выполнения манифестов.)
({{cmd|service puppet start}} собственно и запускает такого агента, но не в одноразовом режиме; мы пока так демона-агента не запускаем, потому что неинтересно для тестирования выполнения манифестов.)
А на том же хосте (puppet), где мастер, получится выполнить тестовый манифест сразу с первого раза этой командой.
Чтобы выполнить на другом хосте, а именно slave0, придётся подписать ключ этого подчинённого хоста (чтобы ходить к puppet-мастеру с этим сертификатом). Это делается просто, если знать; можно просто подписать на puppet-мастере. Перед началом работы на puppet-мастере видим только свой сертификат (подписанный -- отмечено <tt>+</tt>):<pre>
[root@puppet ~]# puppet cert list --all
+ "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")
</pre>
а после первого вызова агента на подчинённом хосте (обычным образом, т.е. так, как указано выше: {{cmd|puppet agent --test --debug}}) в этом списке появится его ключ:<pre>
[root@puppet ~]# puppet cert list --all
  "slave0.localdomain" (SHA256) 4C:D1:8F:00:76:FD:A1:50:D5:BD:3F:4F:C7:69:E0:1E:17:1E:EC:9F:B0:F6:D2:32:2E:C3:4C:F0:99:71:88:C7
+ "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")
</pre>
(имя явно берётся не из DNS мастером, потому что имени slave0.localdomain мастеру неизвестно; оно было вписано подчинённой нодой при создании запроса на подпись сертификата). Подписываем:<pre>
[root@puppet ~]# puppet cert sign slave0.localdomain
Signing Certificate Request for:
  "slave0.localdomain" (SHA256) 4C:D1:8F:00:76:FD:A1:50:D5:BD:3F:4F:C7:69:E0:1E:17:1E:EC:9F:B0:F6:D2:32:2E:C3:4C:F0:99:71:88:C7
Notice: Signed certificate request for slave0.localdomain
Notice: Removing file Puppet::SSL::CertificateRequest slave0.localdomain at '/etc/puppet/ssl/ca/requests/slave0.localdomain.pem'
[root@puppet ~]# puppet cert list --all
+ "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")
+ "slave0.localdomain" (SHA256) 1A:2A:15:08:F4:AD:0B:3A:CA:46:EF:2A:B5:0D:60:4E:DC:BA:BA:E2:63:EC:D1:A3:84:4A:06:B3:9A:A4:22:ED
</pre>
После этого повторный запуск {{cmd|puppet agent --test --debug}} на подчинённой ноде выполняет наш тестовый манифест!<ref>
повторный запуск {{cmd|puppet agent --test --debug}} на подчинённой ноде выполняет наш тестовый манифест:<pre>
...
Debug: Caching connection for https://puppet:8140
Info: Caching catalog for slave0.localdomain
Debug: Creating default schedules
Info: Applying configuration version '1485527400'
Notice: /Stage[main]/Main/File[/tmp/puppet-testfile]/ensure: defined content as '{md5}2f09fcc0123eb12d2b07a2a87135a278'
Debug: /Stage[main]/Main/File[/tmp/puppet-testfile]: The container Class[Main] will propagate my refresh event
Debug: Class[Main]: The container Stage[main] will propagate my refresh event
Debug: Finishing transaction 16750420
Debug: Storing state
Info: Creating state file /var/lib/puppet/state/state.yaml
Debug: Stored state in 0.06 seconds
Notice: Applied catalog in 0.11 seconds
Debug: Dynamically-bound server lookup failed, falling back to report_server setting
Debug: Dynamically-bound port lookup failed; falling back to report_port setting
Debug: Using cached connection for https://puppet:8140
Debug: Caching connection for https://puppet:8140
Debug: Closing connection for https://puppet:8140
[root@slave0 ~]# l /tmp/p*
-rw-rw-r-- 1 root root 83 янв 27 17:30 /tmp/puppet-testfile
</pre></ref>
==См. также==
* [[Puppet/Запуск puppetry (инструкция для PVE)]]


==Примечания==
==Примечания==
<references />
<references />

Текущая версия от 20:12, 12 сентября 2017


Stub.png
Данная страница находится в разработке.
Эта страница ещё не закончена. Информация, представленная здесь, может оказаться неполной или неверной.


цель
  • Виртуальная сеть с виртуальными машинами для тестирования отработки манифестов puppet на подчинённых нодах с ALT-ом.
  • Образы для таких виртуальных машин.

Помимо прочего на этой странице получилось своеобразное руководство к некоторым командам virt-* (для libvirt). Приветствуются исправления и дополнения к этому тексту (и пакетам и образам)!

Нерешённые проблемы и задачи

Перечень нерешённых сейчас проблем и задач, решение которых нужно для успешного запуска ALT puppetry (кем угодно из сообщества по этой инструкции):

  1. Symbol support vote.svg описано как Выполнение манифеста на другой ноде. -- #Тестирование puppet
  2. Проверка и адаптация к ALT базовых средств, модулей puppet (пакетный менеджер в первую очередь, задействованный при работе некоторых других модулей). -- task #175947 test-only sisyphus ruby-facter.git=2.0.1-alt2 puppet.git=4.8.1-alt1
  3. Подготовка образа для тестирования puppet.

И перечень задач, ради совместного решения которых пригодится ALT puppetry (к чему готовиться?):

  • Проверка и адаптация к ALT прочих модулей.
  • Как эти наработки по адаптации интегрировать в экосистему puppet (upstream) и в ALT Sisyphus? Как гарантировать консистентность того, что записано в исходниках puppet и его модулей, и пакетов ALT Sisyphus?

Такой вопрос касается:

  1. консистентности внутри ALT Sisyphus:
    -- Все изменения для puppet и управляемых пакетов общего назначения полностью под контролем ALT, но как формализовать зависимости, проверки?
  2. ситуации когда к людям попадает upstream-ный puppet-мастер (крутящийся на какой угодно ОС), но часть подчинённых нод с ALT:
    -- А может ли подчинённая нода хранить некоторые знания о своих особенностях (особенностях ALT) и влиять на выполняемые по заказу мастера действия, когда мастер не имеет информации обо всех особенностях ALT? Это бы позволило перенести достижения разработки в ALT Sisyphus на такой случай.
  3. предыдущей ситуации, суженной до конкретного специализированного дистрибутива с puppet-мастером и некоторым набором пакетов, рассчитанного на то, чтобы управлять подчинёнными нодами в т.ч. на ALT (с использованием пакетов из этого подготовленного набора).
    -- Ввиду уже сформулированных общих вопросов про разработку и проверку внутри ALT Sisyphus и интеграцию с upstream-ным puppet-ом остаётся вопрос о том, как упростить создание (или адаптацию для ALT) таких дистрибутивов.

(Дополнительно к решению всех озвученных проблем в лоб, есть мысли обратиться к distrodb/distromap, чтобы "переводить" использование пакетов других дистрибутивов в пакеты ALT для стыковки с puppet-ом ALT-овых нод.)

Оформление инструкций в этом руководстве

Изменяемые (по вкусу каждого пользователя) параметры в примерах я старался выделять жирным, чтобы можно было их легко отличить от определённых не нами штук с жёстко заданными именами.


Создание сети

цель
В сети у нас будет свой DNS (для обращения к puppet по имени), и для удобства -- свой DHCP-сервер. При этом хотелось бы сохранить возможность выхода в "интернет" (сеть хост-системы).

Такая сеть таким образом (как нам нужно) будет использоваться, когда машина будет создаваться virt-install --network network=puppettheatre (а не --network bridge=BRIDGE; см. man virt-install).

(BUG: Чтобы запустить такую сеть, как мы делаем, нужен /dev/net/tun. Его может не быть в системе без systemd (altbug 31718#c27). Появлется после загрузки модуля: modprobe tun или описанным действием, которого сейчас не хватает: /sbin/systemd-tmpfiles --prefix=/dev --create --boot.)

(удобно) КОМАНДОЙ

???

(неудобно) ВРУЧНУЮ через GUI virt-manager

(Использовался virt-manager-1.4.0-alt1.)

virt-manager > Edit > Connection Details > Virtual Networks

+ (Add Network)

Тип такой сети, как нам нужна, будет называться "Isolated Physical Network".

Параметры в итоге получаются такие:

Name
puppettheatre
Device
some vibrNN
Domain
theatre (??? для чего используется? для чего важно?)
Network
e.g., 192.168.121.0/24
Gateway
будет автоматически выставлен в 192.168.121.1;
Static routing
наверное, не нужно;
DHCP range
Disabled
Forwarding
NAT

Создание машины с ALTовым puppet-мастером

(BUG altbug #33801: требуется установить qemu; по зависимостям libvirt-daemon-driver-qemu оно не вытягивается.)

(удобно) КОМАНДОЙ

???

(неудобно) ВРУЧНУЮ через GUI инсталлятора alterator через virt-viewer

(Использовался virt-viewer-5.0-alt1, virt-install-1.4.0-alt1, libvirt-1.3.2-alt1, а также более поздние версии.)

Пример:

virt-install --virt-type kvm \
  --name imz-puppetry0-master-ALT \
  --memory 1024 --disk size=10 \
  --cdrom /space/iso/nightly/tested/regular-lxde-latest-x86_64.iso \
  --network network=puppettheatre \
  --os-variant altlinux7.0
  • --name imz-puppetry0-master-ALT -- какое-нибудь имя;
  • regular-lxde-latest-x86_64.iso выбран как небольшой образ для инсталляции системы с systemd (сначала грузится LiveCD, что пока не важно, хотя есть планы тестировать puppet-мастер прямо с LiveCD); до исправления altbug #33334 рекомендуется использовать рабочий архивный образ /space/iso/nightly/archive/regular-tde-20170111-x86_64.iso, а после настройки доступа по ssh сделать apt-get dist-upgrade;
  • --network network=... прокомментирован выше в #Создание сети;
  • --os-variant altlinux7.0 просто выбран как самый свежий из известных ему ALTовых. (В man-странице из virt-install-1.4.0-alt1 и позже сказано посмотреть варианты командой osinfo-query os; оно из пакета libosinfo-1.0.0-alt1; раньше было немного по-другому.)

Запуск машины

См. #Запуск машин.

Конфигурация сети на машине

(Конфигурация сети на машине задаётся, конечно, вручную -- во время инсталляции или через alterator или привычным образом через конф.файлы.)

[user@puppet ~]$ tail /etc/sysconfig/network /etc/net/ifaces/eth0/*
==> /etc/sysconfig/network <==
# Used by hotplug/pcmcia/ifplugd scripts to detect current network config
# subsystem.
CONFMETHOD=etcnet

# Used by rc.sysinit to setup system hostname at boot.
HOSTNAME=puppet.localdomain

# This is used by ALTLinux ppp-common to decide if we want to install
# nameserver lines into /etc/resolv.conf or not.
RESOLV_MODS=yes

==> /etc/net/ifaces/eth0/ipv4address <==
192.168.121.2/24

==> /etc/net/ifaces/eth0/ipv4route <==
default via 192.168.121.1

==> /etc/net/ifaces/eth0/options <==
TYPE=eth
CONFIG_WIRELESS=no
BOOTPROTO=static
CONFIG_IPV4=yes

==> /etc/net/ifaces/eth0/resolv.conf <==
nameserver 10.4.0.1
[user@puppet ~]$ 
  • Здесь имя машины сделано puppet специально.
  • IP-адрес назначен произвольно из доступного диапазона. (Один из адресов этой сети уже использован для шлюза -- хост-системы с гипервизором.)
  • Т.к. в сети есть NAT для связи со внешним миром, мы можем использовать наш реальный DNS из внешнего мира. (Был прописан вручную, конечно.)

Удалим мешающееся для настройки сети:

apt-get remove NetworkManager

Напоследок включим sshd для входа по сети (правда, только с хост-системы, потому что IP нашей виртуальной машины за NAT.)

Общие добавочные костыли и плюшки в конфигурации

Добавочные "костыли" в конфигурации этой создаваемой ВРУЧНУЮ машины делаем ради удобства/быстроты получения уже чуточку сконфигурированных подчинённых машин как клонов.

TODO: Планируется реализовать эту добавочную конфигурацию более прозрачными, чем костыли, способами: сетевыми сервисами; внести всё потребовавшееся и описанное на этой странице в запланированный нами профиль для mkimage (образ VM/LiveCD для тестирования puppet в сети-песочнице -- "puppetry.img/.iso").

  • Скорее всего нам будет удобно ходить на эти машины по ssh, так что убедимся что sshd включен и настроен. (Остальные действия можно будет делать по ssh.)
  • Пусть клоны видят свой puppet-мастер по имени на фиксированном IP-адресе (этой машины):
echo '192.168.121.2 puppet' >>/etc/hosts
  • Можно поставить какие-то любимые пакеты сейчас, перед тем, как эта машина будет использована как исходник для клонирования; например:
apt-get update; apt-get install emacs25-X11-gtk3 emacs-misc-modes emacs-prog-modes slocate apt-printchanges telnet lsof moreutils
systemctl enable crond
updatedb
  • Для удобства положим технический SSH-ключ:
[root@vb ~]# rsync -avP ~/.ssh/id_rsa.pub user@192.168.121.2:.ssh/hypervisor-id_rsa.pub
[root@vb ~]# ssh user@192.168.121.2 'cat .ssh/hypervisor-id_rsa.pub >>.ssh/authorized_keys'
[root@vb ~]# ssh user@192.168.121.2 -t su -c "'cat ~user/.ssh/hypervisor-id_rsa.pub >>/root/.ssh/authorized_keys'"

Используем машину как исходник для клонирования

Прежде, чем что-то делать с машиной, используем её как исходник для клонирования и создания других (подчинённых) нод с ALT, чтобы не повторять инсталляцию вручную.

Думаю, удобно будет её сохранить в первоначальном виде и не трогать эту копию. (А копию уже использовать как исходник для всяких ALTовых нод.)

ssh user@192.168.121.2 -t su -c /sbin/poweroff; ping 192.168.121.2
virt-clone --original imz-puppetry0-master-ALT --auto-clone

Заметьте, что сеть будет использоваться та же самая -- как нам и нужно (для общения создаваемых нод между собой).[1]

Для удобства будущей перенастройки новых клонов этого клона без выключения других машин (без коллизии с IP-адресом работающего puppet-мастера) я бы в клоне сразу поменял IP-адрес на некий выделенный временный, как это делается потом для всех рабочих подчинённых нод, например, 192.168.121.16:

[root@vb ~]# virsh start imz-puppetry0-master-ALT-clone
[root@vb ~]# ssh root@192.168.121.2
[root@puppet ~]# emacs /etc/net/ifaces/eth0/ipv4address 
[root@puppet ~]# cat /etc/net/ifaces/eth0/ipv4address 
192.168.121.16/24
[root@puppet ~]# poweroff

Создание подчинённой машины с ALTом

(удобно) КОМАНДОЙ

???

(неудобно) ВРУЧНУЮ: склонируем что-то; сконфигурируем

Для простоты склонируем созданную ВРУЧНУЮ машину; у нас уже заготовлена копия; её склонируем и сконфигурируем потом:

virt-clone --original imz-puppetry0-master-ALT-clone --name imz-puppetry0-slave0-ALT --auto-clone

Сконфигурируем сеть (пока исходник клона опущен), зайдя по ssh по старому IP-адресу:

[root@vb ~]# virsh start imz-puppetry0-slave0-ALT; ping 192.168.121.16
[root@vb ~]# ssh user@192.168.121.16
[user@puppet ~]$ su -
# emacs /etc/net/ifaces/eth0/ipv4address /etc/sysconfig/network 

Назначим новый IP-адрес и имя, убдимся, что по имени puppet мы можем обратиться к puppet-мастеру:

[root@puppet ~]# tail /etc/net/ifaces/eth0/ipv4address /etc/sysconfig/network /etc/hosts
==> /etc/net/ifaces/eth0/ipv4address <==
192.168.121.3/24

==> /etc/sysconfig/network <==
# Used by hotplug/pcmcia/ifplugd scripts to detect current network config
# subsystem.
CONFMETHOD=etcnet

# Used by rc.sysinit to setup system hostname at boot.
HOSTNAME=slave0.localdomain

# This is used by ALTLinux ppp-common to decide if we want to install
# nameserver lines into /etc/resolv.conf or not.
RESOLV_MODS=yes

==> /etc/hosts <==
127.0.0.1	localhost.localdomain localhost
192.168.121.2 puppet
[root@puppet ~]# 

Можно перезагружать: ssh user@192.168.121.16 -t su -c /sbin/reboot; ping 192.168.121.3

Запуск машин

Примеры:

virsh start imz-puppetry0-master-ALT; ping 192.168.121.2
virsh start imz-puppetry0-slave0-ALT; ping 192.168.121.3

Работа с машинами происходит подключением через virt-manager или по ssh с хост-системы-гипервизора.

Остановка машин

Примеры остановки по-хорошему:

ssh root@192.168.121.2 poweroff
ssh user@192.168.121.2 -t su -c /sbin/poweroff

Остановка грубо (подсмотрено в virt-delete из #Удаление машин):

virsh destroy imz-puppetry0-master-ALT

(это именно аналог выключения питания, а не удаление образов).

Удаление машин

Если нужно, удаление той или иной машины делается[1] так, как записано в скрипте virt-delete из virt-utils.

Тестирование puppet

Предварительные штуки: пакеты, сервисы

[root@puppet ~]# apt-get install puppet-server 
[root@slave0 ~]# apt-get install puppet
[root@puppet ~]# service puppetmaster start
[root@puppet ~]# systemctl enable puppetmaster

Демона агента на подчинённой ноде пока запускать не будем, потому что тестировать интереснее однократным вызовом с отладочной информацией (как будет ниже в примере: puppet agent --test --debug):

[root@slave0 ~]# #service puppet start

Создание и выполнение тестовых манифестов

Место, где лежат манифесты, которые будут выполнятся (в конфигурации по умолчанию). (В конфигурации по умолчанию агент обращается к мастеру на хосте по имени puppet.)

[root@puppet puppet]# mkdir -p /etc/puppet/environments/production/manifests

В Puppet3 нужно отредактировать файл /etc/puppet/puppet.conf, добавив в секцию Main следующий код:

environmentpath = $confdir/environments

Затем нужно перезапустить puppetmaster.

Попробуем простейший пример манифеста (эта ссылка просто на пример исходного кода для puppet; команды для тестирования все перечислены и на нашей странице; нет необходимости пробовать, например, puppet apply). Этот пример манифеста создаст /tmp/puppet-testfile. В начале работы его нет:

[root@slave0 ~]# l /tmp/puppet-testfile
ls: cannot access /tmp/puppet-testfile: No such file or directory

Сам манифест:

[root@puppet puppet]# cat >/etc/puppet/environments/production/manifests/test0.pp
file { "/tmp/puppet-testfile":
        ensure => "present",
        owner => "root",
        group => "root",
        mode => "664",
        content => "This is a test file created using puppet.
                    Puppet is really cool",
}

Выполнить его на slave0, возможно, не получится с первого раза (см. решение про подпись ниже), но попробовать запустить агент можно всё равно сразу, и пробовать сколько угодно раз. Перезапускать puppetmaster не нужно, чтобы читался новый манифест. Имя .pp-файла не важно. Одноразовое тестирование выполнения с отладочной информацией делается командой:

puppet agent --test --debug
l /tmp/pup*

(service puppet start собственно и запускает такого агента, но не в одноразовом режиме; мы пока так демона-агента не запускаем, потому что неинтересно для тестирования выполнения манифестов.)

А на том же хосте (puppet), где мастер, получится выполнить тестовый манифест сразу с первого раза этой командой.

Чтобы выполнить на другом хосте, а именно slave0, придётся подписать ключ этого подчинённого хоста (чтобы ходить к puppet-мастеру с этим сертификатом). Это делается просто, если знать; можно просто подписать на puppet-мастере. Перед началом работы на puppet-мастере видим только свой сертификат (подписанный -- отмечено +):

[root@puppet ~]# puppet cert list --all
+ "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")

а после первого вызова агента на подчинённом хосте (обычным образом, т.е. так, как указано выше: puppet agent --test --debug) в этом списке появится его ключ:

[root@puppet ~]# puppet cert list --all
  "slave0.localdomain" (SHA256) 4C:D1:8F:00:76:FD:A1:50:D5:BD:3F:4F:C7:69:E0:1E:17:1E:EC:9F:B0:F6:D2:32:2E:C3:4C:F0:99:71:88:C7
+ "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")

(имя явно берётся не из DNS мастером, потому что имени slave0.localdomain мастеру неизвестно; оно было вписано подчинённой нодой при создании запроса на подпись сертификата). Подписываем:

[root@puppet ~]# puppet cert sign slave0.localdomain
Signing Certificate Request for:
  "slave0.localdomain" (SHA256) 4C:D1:8F:00:76:FD:A1:50:D5:BD:3F:4F:C7:69:E0:1E:17:1E:EC:9F:B0:F6:D2:32:2E:C3:4C:F0:99:71:88:C7
Notice: Signed certificate request for slave0.localdomain
Notice: Removing file Puppet::SSL::CertificateRequest slave0.localdomain at '/etc/puppet/ssl/ca/requests/slave0.localdomain.pem'
[root@puppet ~]# puppet cert list --all
+ "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")
+ "slave0.localdomain" (SHA256) 1A:2A:15:08:F4:AD:0B:3A:CA:46:EF:2A:B5:0D:60:4E:DC:BA:BA:E2:63:EC:D1:A3:84:4A:06:B3:9A:A4:22:ED

После этого повторный запуск puppet agent --test --debug на подчинённой ноде выполняет наш тестовый манифест![2]

См. также

Примечания

  1. Посмотрите, что получилось с клоном:
    [root@vb ~]# diff -du <(virsh dumpxml imz-puppetry0-master-ALT)  <(virsh dumpxml imz-puppetry0-master-ALT-clone)
    --- /dev/fd/63	2017-01-24 14:04:17.089573354 +0300
    +++ /dev/fd/62	2017-01-24 14:04:17.089573354 +0300
    @@ -1,6 +1,6 @@
     <domain type='kvm'>
    -  <name>imz-puppetry0-master-ALT</name>
    -  <uuid>887ffdb5-3222-4717-8b13-820c1ba543ad</uuid>
    +  <name>imz-puppetry0-master-ALT-clone</name>
    +  <uuid>463057db-4470-4b6a-b44b-6f19d8040793</uuid>
       <memory unit='KiB'>1048576</memory>
       <currentMemory unit='KiB'>1048576</currentMemory>
       <vcpu placement='static'>1</vcpu>
    @@ -32,7 +32,7 @@
         <emulator>/usr/bin/qemu-kvm</emulator>
         <disk type='file' device='disk'>
           <driver name='qemu' type='qcow2'/>
    -      <source file='/var/lib/libvirt/images/imz-puppetry0-master-ALT.qcow2'/>
    +      <source file='/var/lib/libvirt/images/imz-puppetry0-master-ALT-clone.qcow2'/>
           <target dev='vda' bus='virtio'/>
           <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
         </disk>
    @@ -65,7 +65,7 @@
           <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
         </controller>
         <interface type='network'>
    -      <mac address='52:54:00:60:5e:ca'/>
    +      <mac address='52:54:00:e3:ae:bd'/>
           <source network='puppettheatre'/>
           <model type='virtio'/>
           <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    [root@vb ~]# 
    
  2. повторный запуск puppet agent --test --debug на подчинённой ноде выполняет наш тестовый манифест:
    ...
    Debug: Caching connection for https://puppet:8140
    Info: Caching catalog for slave0.localdomain
    Debug: Creating default schedules
    Info: Applying configuration version '1485527400'
    Notice: /Stage[main]/Main/File[/tmp/puppet-testfile]/ensure: defined content as '{md5}2f09fcc0123eb12d2b07a2a87135a278'
    Debug: /Stage[main]/Main/File[/tmp/puppet-testfile]: The container Class[Main] will propagate my refresh event
    Debug: Class[Main]: The container Stage[main] will propagate my refresh event
    Debug: Finishing transaction 16750420
    Debug: Storing state
    Info: Creating state file /var/lib/puppet/state/state.yaml
    Debug: Stored state in 0.06 seconds
    Notice: Applied catalog in 0.11 seconds
    Debug: Dynamically-bound server lookup failed, falling back to report_server setting
    Debug: Dynamically-bound port lookup failed; falling back to report_port setting
    Debug: Using cached connection for https://puppet:8140
    Debug: Caching connection for https://puppet:8140
    Debug: Closing connection for https://puppet:8140
    [root@slave0 ~]# l /tmp/p*
    -rw-rw-r-- 1 root root 83 янв 27 17:30 /tmp/puppet-testfile