Сколько копий было сломано об эту связку — не счесть. Форум обоих продуктов ломится от вопросов. Но вот ответов, как и вопросов, подобным моим, я там не нашел. Ну или по крайней мере внятных ответов на них.

Вопросов-то, у меня было всего два:
  1. Как заставить изменяться счетчик отпечатанных страниц для сетевых принтеров? FusionInventory внутри себя хранит значение, полученное по SNMP при инвентаризации, а вот основное поле не обновляет.
  2. Как запустить инвентаризацию на бездисковых станциях под управлением Thinstation? Как и в любой не слишком большой компании, денег на лицензирование дают скрипя зубами на всю округу, да и то раз в пятилетку. Как следствие — имеется разномастный парк бездисковых станций, собранных из того, что было под рукой.

Естественно, хотелось решить оба вопроса не вставая со стула. Пусть техники не так много, но территориально она в нескольких регионах, так что всех не обойдешь.

Все дальнейшие телодвижения осуществлялись на следующей конфигурации: виртуальная машина KVM, 1Gb ОЗУ, 10 GB HDD, Debian 7, GLPI 0.85.4, FusionInventory Plugin 1.2

С первым вопросом все оказалось достаточно просто. Все значения хранятся в MySQL, так что оставалось лишь найти все зависимости и проверить, не ломает ли прямая запись в базу какой либо учет внутри GLPI.

По итогу, получился вот такой вот скрипт (Осторожно: Быдлокод!):

#!/bin/bash

msql_u='glpi' #Пользователь MySQL
msql_p='glpi' #Пароль MySQL
msql_db='glpi' #БД MySQL

mysql -u $msql_u -p$msql_p -D $msql_db -B -N -s -e 'select id,last_pages_counter from glpi_printers where (have_ethernet = 1);'| while read -r line
do
printer_glpi_counter=$(echo $line | awk '{print $2}')
printer_ip=$(mysql -u $msql_u -p$msql_p -D $msql_db -B -N -s -e "SELECT name FROM glpi_ipaddresses WHERE mainitems_id = $(echo $line | awk '{print $1}') AND mainitemtype = 'Printer';")
printer_cur_counter=$(snmpwalk -Ovq -c public -v 1 $printer_ip 1.3.6.1.2.1.43.10.2.1.4.1.1 2>/dev/null)
if [ $printer_cur_counter -gt $printer_glpi_counter ] ;
  then
    mysql -u $msql_u -p$msql_p -D $msql_db -B -N -s -e "UPDATE glpi_printers SET last_pages_counter=$printer_cur_counter,date_mod=NOW() WHERE id=$(echo $line | awk '{print $1}')"
fi
done

Используется две таблицы:
  • glpi_printers — содержит имя принтера, коммуникации на его борту (отбираем только сетевые — where (have_ethernet = 1)), счетчики, и кучу прочей информации
  • glpi_ipaddresses — содержит ip-адреса сетевых устройств, их тип, и id этого устройства

Текущий счетчик страниц получаем с принтера по SNMP, сравниваем его с текущим в GLPI и если он больше — записываем в базу и меняем дату изменения записи.

Неделя тестов показала, что учет ведется верно, ничего не ломается и скрипт был натравлен на рабочий GLPI. Результатом явиласть вот такая картина:

image

Странно, что картридж повышенной емкости отпечатал на 100 страниц больше. А я думал, мне только казалось, что меняются они с приблизительно одинаковым интервалом. Но это уже вопросы к тем, кто их заправляет.

Второй же вопрос поставил мою лень в тупик. Либо пересобирать thinstation, что тянет за собой очередные головные боли с rdesktop, freerdp, звуком и модулями, либо максимально кастрировать perl, ибо fusioninventory-agent написан целиком и полностью на нем, и собирать свой модуль.

Собственно, победил второй вариант, так как лишний раз утяжелять сборку не хотелось, а инвентаризация — дело не требующее повседневности, раз в неделю запустил и нормально.

За пару дней неспешного копания агента, были выянены необходимые (ну и собственно штатные) утилиты для инвентаризации железа: lspci, lsusb, fdisk, arch, dmidecode, get-edid, ifconfig, parse-edid и прочие. Вот тут был выявлен первый подводный камень: lspci, fdisk и многие другие утилиты в Thinstation — всего лишь алиасы к busybox и с необходимыми ключами, естественно, не работают.

Вторым подводным камнем было определение архитектуры. Почему-то агент получал значение linux-thread-multi и дальше все стопорилось, поскольку обработка такой архитектуры не предусмотрена. Пришлось ставить костыль в Agent/Task/Inventory/Linux/i386.pm:

Было:

return $Config{archname} =~ /^(i686|x86_64)/;

Стало:

return $Config{archname} =~ /^(i686|x86_64|linux-thread-multi)/;

Остальные камни были из серии «нужная утилита работает не так, значения не возвращает, поэтому инвентаризировать не будем». Для исправления пришлось заталкивать в сборку lspci, lsusb, fdisk, arch, dmidecode, get-edid, parse-edid и менять в скриптах агента пути к этим утилитам. Странно, но почти все пути были прописаны как абсолютные. Ну да это уже дело разработчиков.

Исполняемый скрипт, запускающий агента, получился вот таким:
#!/bin/sh
export PERL5LIB=/FusionInventory/perl/lib/:/FusionInventory/agent/:/FusionInventory/perl/agent/:/FusionInventory/perl/site/lib:/FusionInventory/perl/vendor/lib/
cd /FusionInventory/perl/bin
./perl fusioninventory-agent -f

Скрипт запускается кроном, два раза в день инвентаризации. День инвентаризации выбирается самостоятельно. У меня — каждый понедельник.
Первая рабочая сборка модуля родилась большой по размеру — 13 мб. Но зато работала. И работала на ура.
Скрины инвентризированного Thinstation





В результате «доработки напильником» размер модуля уменьшился до 5.1 мб. Больше выкидывать просто нечего.

Ссылка на финальную версию модуля

Перед использованием модуля, в нем необходимо поправить путь к Вашему GLPI. Файл открывается и распаковывается как обычный tar.gz архив. Править файл ./FusionInventory/etc/agent.cfg
Знаю, что это недоработка, но я не нашел, как можно получать свои параметры из thinstation.conf.network при загрузке.

Спасибо за внимание!

За информацию по Thinstation спасибо сайту thinstation.pro, объяснившему мне, как собирать свои модули для тонких клиентов.

UPD:
Разобрался с передачей параметров. Теперь, чтобы задать адрес сервера инвентаризации, достаточно в файле thinstation.conf.network добавить строку
FUSION_SERVER="http://адрес_вашего_сервера/plugins/fusioninventory/"

Комментарии (2)


  1. kvaps
    02.09.2015 19:48
    +1

    Вот смотришь со стороны, прикольно это у вас это все получилось.
    А тем временем вспоминаешь, как ставил как то раз такую же связку GLPI+FusionInvertory, и было с ней далеко не все гладко.
    На тот момент правда был нужен в первую очередь сервисдеск, а не инвентаризация, но вот он то больше всего и не понравился. Во первых какое то дико нелогичное (на мой взгляд) разделение по организациям, так же частенько натыкаешься на какие то глючные или не работающие формы/кнопки. А во вторых не понравилось, что что бы создать какой-нибудь тикет, необходимо что бы пользователь обязательно существовал в системе.
    Но с другой стороны с таким подходом GLPI и в правду больше подходит для инвентаризации.

    Я рад что вам удалось реализовать все хотелки, у нас он, к сожалению, не прижился.


    1. KhvPhoenix
      03.09.2015 00:40

      Ну у нас он тоже изначально был запущен как сервисдеск. И проработал пару лет именно в таком режиме.
      Существование пользователей решилось интеграцией с АД. Так или иначе все сотрудники у нас есть в домене. Мы — торговая компания и отдел не обслуживает посторонних (по крайней мере официал ьно).
      Просто руководитель отдела уволился, нового пока не нашли, а когда найдут — наверняка тот захочет увидеть, что в компании есть. Да и вообще, кто знает, какие у него будут запросы.