Archive

Posts Tagged ‘UNIX’

Debian-пакеты с человеческим лицом на примере Zabbix 1.8

March 29th, 2010 No comments

Несколько задержавшийся кросс-пост с хабрахабра, в котором я описываю пример сборки debian-пакета с использованием CDBS.

Написать эту статью меня заставили две вещи: во-первых, вышел zabbix 1.8 – замечательной системы мониторинга, в которой, судя по новостям, наконец-то занялись проблемами юзабилити админского интерфейса. Во-вторых, появилось стойкое ощущение, что после статей “делаем debian-пакет на коленке”, большинство хабравчан утвердятся во мнении, что debian-пакеты придумали извращенцы для извращенцев.

Связывает два этих события то, что zabbix 1.8 пока нет в репозиториях убунты, и когда появится не понятно, а компилить и ставить из исходников что-то на продакшн-серверах, это, конечно, недостойное джентльмена занятие. В общем, появился хороший повод продемонстрировать, что debian-пакеты – это не страшно.

Итак, приступим:

apt-get install dh-make devscripts cdbs libmysqlclient-dev libcurl4-gnutls-dev
wget http://sunet.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/1.8/
tar zxvf zabbix-1.8.1.tar.gz
cd zabbix-1.8.1
dh_make --createorig --cdbs

Между делом, если бы мы пакетировали не zabbix, а более простую программу, которая обычно ставится с помощью ./configure; make; make install, то на этом создание пакета заканчивается. Осталось бы только собрать пакет с помощью команды ar debuild.

Но мы продолжим: откроем файл debian/control и пропишем себя, любимого, в качестве создателя пакета, и укажем, какие пакеты должны приехать на сервер вместе с установкой zabbix. Для этого нужно найти строку ‘Depends’ и добавить в ее конец следующее: “fping, adduser, apache2, php5, php5-mysql, php5-gd”.

Обычно скрипт configure можно вызывать без параметров и он сгенерирует жизнеспособный конфиг, но для zabbix это не так – нужно отдельными опциями включать компиляцию серверной части и агента. Так как агент из репозитория ubuntu меня полностью устраивает, ограничимся сборкой только сервера. Для этого нужно дописать в конец файла debian/rules следующую строку:

DEB_CONFIGURE_USER_FLAGS := --enable-server --with-mysql --with-libcurl

Сборка пакета осуществляется следующим образом: создается временная директория (debian/zabbix), в которую копируется содержимое пакета. Затем эта директория упаковывается в архив, добавляются метаданные, и все – пакет готов. Это очень грубое, но пока достаточное описание процесса. Бинарные файлы попадут в директорию debian/zabbix/usr/bin сами собой (CDBS запустит команду make install DESTDIR=debian/zabbix), а файлы php-интерфейса нам нужно туда поместить вручную. Для этого перечислим их в файле debian/install вот каким образом:

frontends/php/* usr/share/zabbix/
misc/conf/zabbix_server.conf etc/zabbix

Кроме того, для нормальной работы заббиксу нужны еще и директории для лог-файлов и локов. Они тоже являются частью пакета, поэтому создать их нужно прямо в той временной директории. Стандартный способ создания пустых директорий – перечисление их в файле debian/dirs:

/var/log/zabbix-server
/var/run/zabbix-server

Теперь дело за инит-скриптом. В комплекте с заббиксом идет инит-сктипт (misc/init.d/debian/zabbix-server), но без обработки напильником он работать не будет. Поэтому лучше его заменить скриптом из убунты (http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/karmic/zabbix/karmic/annotate/head%3A/debian/zabbix-server-mysql.zabbix-server.init), который нужно сохранить под именем debian/init.

Совсем не лишним было бы настроить logrotate:

cat > debian/logrotate
/var/log/zabbix-server/zabbix_server.log {
daily
rotate 7
compress
missingok
notifempty
create 0640 zabbix zabbix
sharedscripts
}
^D

Раз пакет мы собираем не для кого угодно, а только для себя, то почему бы и не положить конфиг апача рядом с заббикксом:

mkdir misc/apache2-vhosts
cat > misc/apache2-vhosts/zabbix

ServerName zabbix.example.com
ServerAdmin admin@example.com
DocumentRoot /usr/share/zabbix
CustomLog /var/log/apache2/zabbix_access.log combined
ErrorLog /var/log/apache2/zabbix_error_log

^D
echo "misc/apache2-vhosts/zabbix etc/apache2/sites-available" >> debian/install

Иногда недостаточно просто разложить файлики по файловой системе, чтобы настроить среду для исполнения программы. В таких случаях на помощь приходят preinst, postinst, prerm и postrm скрипты, которые выполняются уже на сервере, куда пакет устанавливается. Названия у них вполне понятные, пояcнить нужно только то, что ‘inst’, и ‘rm’ – это фактическая распаковка или удаление содежимого пакета (все той же временной директории debian/zabbix, в нашем случае), кроме того – каждый из этих скриптов может вызываться с разными аргументами в зависимости от ситуации. Нам интересен скрипт postinst, вызывающийся с аргументом configure – нужное место скрипта можно легко найти в шаблоне postinst.ex. Приступим:


cd debian
mv postinst.ex postinst
vim postinst

После строки configure) нужно вставить следующий код:

# Создадим пользователя
useradd zabbix || echo "User zabbix was not added"

# Установим права на рабочие директории
chown zabbix:zabbix /var/log/zabbix-server /var/run/zabbix-server

# В этой директории веб-интерфейс пытается сохранить конфиг-файл, дадим ему на это права:
chown www-data /usr/share/zabbix/conf
chmod 775 /usr/share/zabbix/conf

# Настроим автозапуск сервера:
update-rc.d zabbix-server defaults

# Включим новый virtualhost и перезапустим апач:
a2ensite zabbix
invoke-rc.d apache2 reload

;;

abort-upgrade|abort-remove|abort-deconfigure)

Осталась одна деталь: при стандартных настройках PHP интерфейс заббикса не заведется, нужно править max_execution_time и еще несколько параметров. Если бы мы готовили пакет для домашнего сервера-торрентокачалки, то, конечно, проще было бы поправить php.ini напрямую. Но идеологически более правильно (и это очевидно при коллективной разработке, когда роли админа и разработчика разделены) поместить эти настройки тоже в пакет. Сделать это можно так:


mkdir misc/php.conf
cat > misc/php.conf/zabbix.ini
post_max_size = 16M
max_execution_time = 300
mbstring.func_overload = 2
^D
echo "misc/php.conf/zabbix.ini etc/php5/conf.d" >> debian/install

На этом все, можно собрать пакет с помощью команды debuild, поставить его с помощью dpkg -i и apt-get install -f.

Categories: UNIX Tags: , , , ,

HTTP сервер в одну строку: версия 2.0

August 30th, 2007 49 comments

Идея с HTTP сервером на bash мне не дает покоя.

Вернуться к ней меня побудила.. попытка воспользоваться старой версией: получалсь не очень :)

Поэтому решил довести его до ума. Что-то дописал, что-то выкинул, полчилось следующее:
:;while [ $? -eq 0 ];do nc -vlp 8080 -c'(r=read;e=echo;$r a b c;z=$r;while [ ${#z} -gt 2 ];do $r z;done;f=`$e $b|sed 's/[^a-z0-9_.-]//gi'`;h="HTTP/1.0";o="$h 200 OK\r\n";c="Content";if [ -z $f ];then($e $o;ls|(while $r n;do if [ -f "$n" ]; then $e "<a href=\"/$n\">`ls -gh $n`</a><br>";fi;done););elif [ -f $f ];then $e "$o$c-Type: `file -ib $f`\n$c-Length: `stat -c%s $f`";$e;cat $f;else $e -e "$h 404 Not Found\n\n404\n";fi)';done

Теперь по URL http://ваш_ip:8080/ можно получить доступ ко всем файлам, находящимся в текущим каталоге. Очевидных и прямолинейных способов сменить каталог нет. Как и раньше, протестировано и работает под Linux, bash 3.2.13, и с хоббитовским netcat v1.10 с поддержкой опции -с (запустите netcat -h и посмотрите. Как минимум в Ubuntu, Debian и Fedora Core такая опция есть).

Теперь строка занимает 434 байт, что на 212 больше, чем прошлая версия. И мне кажется, что я с толком потратил эти байты: новый сервер обрабатывает ошибку 404, кроме того, теперь он работает без задержки, которая раньше требовалась для того, чтобы была возможность его остановить с помощью Ctrl-C. Для успешных запросов сервер отдает нормальные заголовки, с размером файла и даже с его MIME-типом. Например:

dainichi@fujitsu:~/backup$ echo "GET /6.1-RELEASE-i386-disc1.iso HTTP/1.1" | nc localhost 8080 | head -n3
HTTP/1.x 200 OK
Content-Type: application/x-iso9660
Content-Length: 529784832

Для удобства можно сохранить его в файл и написать в .bash_profile примерно следующее:alias share='sh ~/bash_httpd.sh'

Да, были попытки его еще уменьшить, но они не увенчались успехом. Есть такой вариант, но он даже больше:
w=while;d=done;e=echo;r=read;echo "true; $w [ @? -eq 0 ];do nc -vlp 8080 -c'($r a b c;f={$e @b|sed 's/[^a-z0-9_.-]//gi'{;h=}HTTP/1.x};o=}@h 200 OK#};c=}Content};if [ -z @f ];then($e @o;ls|(while $r n;do $e }@n
};done));elif [ -f @f ];then $e }@o@c-Type: {file -ib @f{#@c-Length: {stat -c%s @f{#};cat @f;else $e }@h 404 Not Found##404#};fi)';done"|tr "@{}#" '$`"
'|sh
Оставил его, потому что выглядит страшно, детей пугать – самое то :)

Если у вас получится сэкономить еще пару байтов, то милости просим в комментаторскую :)

UPD: 03.09.2007: Код обновлен, в него вошли исправления, которые сделал тов. jetxee, за которые ему большое спасибо.

UPD: 03.09.2007: Я удивлен тому факту, что эта заметка попала в топ news2, спасибо dik’у за то, что добавил ее. Я рад, что она многим показалась интересной.

UPD: 07.09.2007: Товарищ Ed очень здорово прооптимизировал код. Вот, что у него вышло:
while :;do nc -p8080 -vnlc'r=read;e="echo -e";$r a b c;while [ -n "`$e $a|tr -d "\r\n"`" ];do $r a;done;f=`$e $b|sed s/.//`;h="HTTP/1.0";z="404 Not Found\n";[ -z $f ]&&(ls|while $r n;do [ -f $n ]&&$e "$n";done)||([ -f $f ]&&($e "$h 200 OK\r\nContent-Type: `file -ib $f`\n";cat $f)||$e "$h $z\n$z")';done

Работоспособность проверялась автором на таблетке Nokia N800, а у меня в Kubuntu 7.04 что-то не заработало. Сегодня вечером буду разбираться :)

p.s. Мне теперь стыдно из-за того, что сам не догадался использовать && и || вместо if..then. :(

p.p.s. stay tuned!

UPD 18.08.2008: О, написали про это безобразие на Хабре, назвали меня извращенцем. Хулиганьё!! :)

Что получится, если скрестить fuse и ssh? ‮[файловая система sshfs]

August 29th, 2007 No comments

А получится sshfs.
sshfs позволит вам монтировать каталоги на удаленных машинах по протоколу SFTP; пользоваться им настолько просто, что даже рассказать в этой заметке практически нечего: ни тебе интрижки с накладыванием патчей и сборкой пакета, ни тебе объектного языка конфигурационных файлов. Тоска, одним словом.

Но для sshfs это, вобщем-то, плюс. Итак, начнем с установки пакета и добавления себя в группу fuse, делается это так:
apt-get install sshfs
sudo adduser your_name fuse

Команда adduser в таком контексте ничего, кроме добавления уже существующего пользователя в группу не делает, так что не нужно смущаться от ее неожиданного выхода на сцену. После этого нам нужно перелогиниться, чтобы изменения в /etc/group вступили силу.

Мне пришлось выполнить еще одну операцию: сменить группу у устройства /dev/fuse. Я думаю, это особенность лично моего дистрибутива, но если у вас тоже попытки монтирования будут завершаться ошибкой “что-то там permission denied”, то вот вам команда:
chgrp fuse /dev/fuse
По-хорошему, ее надо прописать куда-нибудь в автозагрузку, например, в /etc/rc.local.

Теперь все готово для монтирования:
mkdir mount_point
sshfs remoteuser@remotehost:/some/folder ~/mount_point
ls mount_point

Ну вот, собственно, и все, можно работать.

Теперь настало время рассказать об одном ограничении: кроме нас, никто в системе не сможет воспользоваться примонтированным каталогом. Сама возможность пустить туда других пользователей есть, но корректность операций записи не гарантируется (могут быть повреждены атрибуты файла – владелец и пр.). Поэтому перед тем, как открывать доступ к важным данным лучше все-таки поставить эксперимент на копии. Также несколько странные результаты будет выдавать команды du и df, но по-моему, это я уже придираюсь :)

В итоге, мы имеем отличную замену scp/sftp или fish (встроенная в mc и konqueror оболчка для sftp) для случаев, когда нужно выполнить действия посложнее, чем копирование.

Дальнейшее чтение: FAQ по sshfs, Другие основанные на fuse файловые системы

Categories: UNIX, tips Tags: , , ,

Программерские загогулины [2]

August 23rd, 2007 8 comments

Очередная программерская загогулина, на этот раз решение сразу не дам :)

Допустим, надо выполнить какую-либо команду на нескольких хостах, перечисленных в файле. Пишу:

cat file | (
while read host; do
ssh user@$host "command"
done
)

Ошибка, однако! В чем?
Кто сможет разобраться в уме, не запуская код, тому респект и уважуха :)

UPD:

Решил человек, скрывающийся под ником gds:

поток из “cat file” будет выкушан только первой запущенной командой “ssh …”?

gds, респект тебе уважуха :)

Удаленный рабочий стол. UNIX-way :)

August 6th, 2007 5 comments

Как всегда, существует уйма способов запускать графические программы удаленно. Не все из них основаны на туннелинге X-трафика, но именно с ним играться интересней всего.

Приступим :)

Собственно, на практике страшная фраза “сделать туннелинг Х-протокола” обозначает, что нужно добавить опцию X к ssh. Получается, что в простейшем случае запустить удаленную графическую программу можно так:
ssh -X user@host firefox

Kdesktop от других программ ничем не отличается:
ssh -X user@host kdesktop

Удаленный или локальный десктоп? Вот в чем вопрос.
Неудобство последней команды как способа удаленного входа заключается в том, что в случае, если какая-либо оболочка уже запущена, то неизбежны конфликты и долгие раздумья на тему принадлежности какого-нибудь окошка удаленной или локальной машине. Поэтому все что нужно сделать – это использовать подобную команду вместо оболочки.

Я это сделал так:
xinit /usr/bin/ssh -X user@host startkde -- :1
Набирать команду следует из обычной, неиксовой консоли (Ctrl-Alt-F1), и работать она будет только в случае, если на удаленной машине уже лежит наш публичный ключик, т.к. не будет возможности ввести пароль. (что такое публичный ключ). Полный путь к ssh на некоторых дистрибутивах обязателен.

Теперь сочетанием клавиш Ctrl-Alt-F7 и Ctrl-Alt-F9 можно переключаться между локальным и удаленным рабочим столом (хотя F9 для удаленной машины – это лично у меня, у вас может быть также F8 или F10). Да, и делать это лучше только если соединение между машинами быстрое, иначе нервных расстройств не избежать :)

Этот пост написан с рабочего десктопа, но через ноутбучную оперу :)

А что интересного с помощью ssh удавалось сделать вам?

UPD через 20 мин: Отправил ноутбук в ребут и через некоторое время понял, что работаю на удаленной машине. 5 секунд паники, 10 – на сохранение и минута чтобы понять, что я ошибся :) Вобщем, для людей со слабым сердцем не рекомендую так работать, а сам я теперь осторожен, как сапер на минном поле :)

Categories: UNIX, tips, общее Tags: , , , ,

Perl и фиксированные ключи в хеше.

July 5th, 2007 No comments

Некоторое время назад мне приходилось писать довольно большой проект на PHP. Тогда очень хотелось от хешей возможности зафиксировать множество ключей, чтобы не отлавливать по десяткам файлов опечатки в названиях полей сложных многоуровневых структур данных.

Тогда решения не нашлось. И сейчас PHP для меня лично уходит потихоньку в прошлое, т.к. в perl нахожу все больше интересных возможностей, которых раньше не хватало.
Так вот, по поводу фиксированного набора ключей, вот пример объекта на основе такого хеша:

package some;

use warnings;
use strict;
use Hash::Util qw{lock_keys};

sub new
{
my $class = shift;
my %hash;
my @keys = ("one", "two", "three", "four", "five");
my $self = bless \%hash, $class;
lock_keys %hash, @keys;
return $self;
}

1;

Теперь при выполнении инструкция $some->{‘there’} произойдет ошибка:
Attempt to access disallowed key 'there' in a restricted hash at ./test.pl line 11.

Причем сделано это не через Tie, чего я сначала опасался, а собственными средствами компилятора, т.е. должно работать очень быстро.

Но вообще-то, в каждой книге по ООП-прогрммированию обязателно замолвят слово о том, что открытые свойства класса это не очень хорошо, и что их значения предпочтительней изменять с помощью методов. А ведь их лень писать для каждой переменной!! Но хорошие языки тем и отличаются, что на них вовсе не сложно писать красиво и правильно. Смотрим, что предлагает Perl (пример из документации):


package Foo;
use base qw(Class::Accessor);
Foo->mk_accessors('foo'); # или mk_ro_accessors(qw{ one two three }) для read-only полей

my $obj = Class->new({ foo => 42 });
print $obj->foo; # 42
$obj->foo("24");
print $obj->foo; # 24

Ну вот и все! Теперь если захочется изменить поведение объекта таким образом, чтобы при изменении свойства foo, менялось также значение bar, достаточно реализовать самостоятельно нужную функцию, а править использующий класс код не нужно.

Все-таки perl язык великий и могучий, этого у него не отнять!

codepage horror

June 29th, 2007 1 comment

Иногда мне снятся сны. Бывает, что кошмары. Что такое кошмар для админа? Это когда видишь свой сайт – все работает, все грузится, но кодирЛЮХВ КВЯНЕК ЗИЕОЕИВ!!!

На работе сегодня этот кошмар воплотился: вселился бес в базу и попутал все кодировки. Попутал на славу, так что первый дамп пришлось расшифровать в два приема: utf8->koi и cp1251->koi, а со вторым развлечение было поизощреннее. С каждой перестановкой буквы прыгали издевательски с места на место, подмигивали и смеялись, доводя мой ЙЛЗХмоск до кипения. Но битву они все-так проиграли. После пятой перекодировки cp1251->koi8r из поганцев сгинул злой дух и оборотились они текстом складным и залился дамп в базу и вернулись: юзерам – счастье, а админу – крепкий сон :)

p.s.

А на #freebsd народ показал такой фокус:


#str="трали-вали"; for((i=0; $i<20; i++)); do str=`echo "$str" | iconv -f CP1251 -t KOI8-R`; done;
#echo $str
трали-вали

return 0;

June 27th, 2007 No comments

Я вернулся :)
За время учебного отпуска нагулял отличное рабочее настроение!

В первый рабочий день обратил внимание на небольшой юбилей: 1 год и 4 дня исполнилось моему процессу screen, запущенному на работе, которым я активно пользуюсь по 40 часов в неделю. Слава героям!!

Попутно веду свою маленькую коллекцию программерских загогулин, вот очередной экземпляр:


#!/usr/bin/perl
$var1 = "one|two|three";
$var2 = join('|', split ('|', $var1));

Опрос знакомых программистов показал, что предполагаемым значением $var2 является исходная строка ($var1). PERL думает иначе.

Вся мощь перла с его реально перегруженными функциями именно в этом моменте дала слабину: split в качестве первого аргумента принимает _только_ регулярное выражение, и, соответственно, символ ‘|’ воспринимается как логическое “или”.. Таким образом, в var2 будет “o|n|e||t|w|o”…

Пусть такое поведение и является документированным, меня оно все равно расстраивает..

Kubuntu 7.04

May 17th, 2007 No comments

KNetworkManager screenshotВ новом Kubuntu появилась интереснейшая вещь, которой раньше очень не хватало: маленький апплет, с помощью которого можно быстро сконфигурировть сетевые интерфейсы.

Вдвойне приятно, что WiFi и Bluetooth заработали сами по себе, не требуя к себе внимания (это был камень в огород Fedora Core :)

Ubuntu – офигенный дистрибутив!

Categories: Uncategorized Tags: ,

Feodora Core

March 3rd, 2007 No comments

Недавно linux на моем ноутбуке упал. Зря я доверился ext2: корневая система рухнула после грубого выключения системы (причем сразу же после загрузки). Это стало поводом для продолжения экспериментов, на этот раз подопытным кроликом стала Feodora Core 6.
После Kubuntu новых впечатлений – масса!!
Во-первых, это GNOME, c которым я раньше особо и не сталкивался – я, конечно, его снесу через какое-то время, но что-то в нем все-таки есть, по крайней мере я начинаю понимать людей, которые с ним работают.
Во-вторых, все очень быстро. Пока не понимаю, как такое может быть, но по ощущениям Open Office грузится в полтора-два раза быстрее.
В-третьих, я еще не гуру линукса, для меня довольно важное значение имеет автоопределние оборудования и дефолтная конфигурация: BeryL из коробки – это клево!! И потом, наконец-то заработала функция перехода в спящий режим при закрывании крышки ноутбука!

Но есть и минусы: yum после apt-get – штука очень тормозная. Может секунд 20 выполнять поисковый запрос и еще минуту – проверять зависимости (это при том, что у меня довольно быстрый компьютер). И еще, похоже, что тулзу для понижения тактовой частоты процессора придется искать самостоятельно – при полной зарядке аккумулятора прогнозируемое время работы – полтора часа, что в полтора раза меньше времени работы из-под ubuntu.

Эх!

Categories: UNIX Tags: , , ,