Архив за ‘Одминское’ категория

Sequoia изнутри #1

Август 27th, 2009

Как бэ вступление

По работе возникла необходимость синхронной рабты с кластером БД (4 базы, в которых должны храниться одни и те же данные). Для этого я несколько месяцев подряд писать тулзу data_proc (коммерческая разработка), которая обрабатывает данные в поточном режиме и устойчива к connection-loss/database-failure ошибкам. Единственный недостаток — это хранение данных на локальном диске в виде журналов, объём которых достаточно велик, если база несколько часов находится offline.
Помимо data_proc у нас есть ещё куча других приложений, для которых пришлось писать балансировщик нагрузки для SELECT-запросов, с чем мы успешно справились. Тем не менее, вопрос балансировки нагрузки и кластеризации (с целью упрощения data_proc) остался, и мне предложили разобраться с C-JDBC, о чём я и буду сейчас писать.
» Читать дальше: Sequoia изнутри #1

Рассылка-таки удалась!

Август 25th, 2009

Сегодня повторно разослал письма обратившимся в ЦеСТ по этой форме: http://www.centercest.ru/noindex/exec/oem.run

Заранее извиняюсь перед теми, кому рассылаемое письмо пришло более одного раза: вследствие слишком активной рассылки почтовые сервисы (например, mail.ru) заблокировали письма как спам. Также были проблемы с настройками postfix, которые были исправлены.

Шаблон рассылаемых писем:

» Читать дальше: Рассылка-таки удалась!

Вот так…

Август 24th, 2009

На провайдера надейся, а сам не плошай…

Хотел сделать рассылку письма-уведомления по базе в связи этим.

И скрипт написал, и всё сделал. Ан-нет, подвёл провайдер, у которого ВНЕЗАПНО слетел reverse DNS.

В результате, мейл-сервисы режектят меня как спамера. Хорошо хоть ещё в RBL-ки не попал. Придётся ждать, пока пропишут Reverse DNS, и каяться мейл-сервисам, что я, на самом деле, боролся за благое дело.

Прошу прощения у ЦеСТ за такой FAIL и за задержку рассылки.

Миграция на WordPress

Август 22nd, 2009

Итак, как обещал, пишу свои впечатления от миграции на WordPress.

Прежде всего хочу акцентировать внимание на то, почему я всё же решил «слинять» с LiveJournal. Окончательной причиной такого решения стала тотальная кривость движка ЖЖ, которая меня очень сильно поражает. Почему я для того, чтобы удалить запись, должен жать на 3 кнопки (править — удалить — согласен) вместо того, чтобы воспользоваться всего двумя (удалить — согласен). Зачастую даже путаешься в интерфейсе для того, чтобы совершить простейшую операцию — перейти из личного кабинета в блог и наоборот. Ну а также не удовлетворяют тормоза в работе, сильная перегруженность контента ЖЖ и ВНЕЗАПНО появившаяся реклама.

Тем не менее, недостатки, как выяснилось, у WordPress тоже в наличии, но они не такие большие.
Прежде всего претензии к плагинам, работающими с ЖЖ: ни lj-xp, ни lj-user работать нормально не хотели. Ну если в lj-xp всё не так страшно и ограничивается только мелкими патчами кода, неработающего на новой версии PHP, то о плагине lj-user можно сказать только то, что автор вообще не знал, чего писал. Это просто БЫДЛОКОДИНГ, и результат этого быдлокодинга тупо вешал движок WordPress при, казалось бы, элементаной операции обработки текста. Заведомо практически не зная PHP, я написал нормальный плагин lj-user, который не вгоняет в вечный цикл движок WordPress, и именно поэтому считаю стирание исконного автора из комментариев справедливым.

Именно поэтому я публикую исправленные версии плагинов у себя на сервере:
LJ CrossPost (lj-xp).
LJ User (lj-user).

В общем, надеюсь, вам эти плагины тоже помогут.

SSH over HTTP proxy

Июль 30th, 2009

Ввиду того, что инет на даче пионерский, а работать по ssh всё же иногда нужно, искал способ работы по SSH через http-proxy.

И нашёл хороший вариант: использование тулзы под названием corkscrew
Собирается она легко и не требует особых хитростей в настройке. Для этого достаточно отредактировать файл ~/.ssh/config.
Для доступа к myhost.zone конфига будет выглядеть примерно следующим образом:

Host myhost.zone
ProxyCommand corkscrew proxy-address proxy-port %h %p

Если же потребуется аутентификация прокси, то необходимо создать файл (например, ~/.ssh/proxyauth) и записать в нём строчку:

username:password

Сама же конфига SSH изменится так:

Host myhost.zone
ProxyCommand corkscrew proxy-address proxy-port %h %p ~/.ssh/proxyauth

После этого можно спокойно коннектиться на нужный хост:

sadko@sadko:~>ssh myhost.zone

С отпуска!

Июль 22nd, 2009

Подключил-таки инет на даче.
Стоимость 80 копеек за мегабайт впечатляет.
Немного выводит из себя качество: доступ в сеть только через proxy (по имени пользователя и паролю), в результате чего пока могу глядеть только сайты.
Пытался поднять socks через dante, да что-то не клеится.
Собственно, пробую на такой конфиге:

route {
        method: username
        from: 0.0.0.0/0   to: 0.0.0.0/0   via: 192.168.0.1 port = 3128
        command: connect                 # only thing a httproxy supports.
        proxyprotocol: http_v1.0
}

При этом, переменные окружения установлены как надо:

sadko@sadko:~> export | grep SOCKS
declare -x SOCKS_PASSWORD="********"
declare -x SOCKS_USERNAME="********"

В результате получаю вот такую фигню

Это пипец. Это просто пипец.

Июль 4th, 2009

Стал внезапным участником переезда. Смена 24 квадратных метров жилища на 17 (UPD: 15) — это полная жп…
Простите те, кому что-то в ближайшее время обещал. Скорее всего, не выполню обещания в срок.
Особенно прошу прощения у klark973 , так как, скорее всего, так и не успею написать скрипт к отъезду.

А сейчас пока я большей частью в офлайн. И http://xskernel.org/ тоже временно не пашет.

NVIDIA twin view???

Май 21st, 2009

Вчера протрахался с NVidia TwinView(C)(R)(TM).
Проблема хитрая: есть монитор на ноуте 1280×800 и есть проектор с разрешением 1024×768. Нужно вывести изображение с ноута на проектор с масштабированием 1200×800 -> 1024×768, желательно пропорциональным.
Выяснил, что nvidia linux drivers пока не умеют масштабировать изображение в режиме отображения clone.
То есть, уменьшить 1200×800 -> 1024×768 не получится, зато сделал хитро — просто отцентровал второй монитор по первому. Ну и фиг с ним, что картинка обрезана. Кстати, OpenOffice.org оказался не дурак и вывел презентацию в разрешении проектора (на котором будет демонстрироваться презентация), то есть, 1024×768.

Вот логичный вопрос: миллионы треугольников, пикселей и текселей в секунду, но что мешает сделать нормальную систему масштабирования для X Server? Кстати, насколько я помню, под вендой это ещё на GeForce’ах вторых было.

Может, я чего-то упустил и не знаю истинного лекарства?
Советы приветствуются.

Закопать!

Май 13th, 2009

Всё больше и больше Acer вызывает у меня ненависть.

Почему же? А вот почему. Сегодня ходил знакомиться с новой аппаратурой, которую нам выделили в универе на кафеду в связи с переездом. И увидел… гламурненькие асеры. Посмотрел: да, корпус смотрится модно, клавиатурка и мышка в комплекте красивые. На всех машинах Vista Buisness, чтоб её.

Решил проверить на вшивость, врубил новый комп, который планируется отдать под шлюз. Vista что-то там пыхтела минут 15-20, потом выдала-таки лицензионное соглашение. Соглашаться, ессно, ни с лицензией Microsoft, ни с Acer, не стал, вставил openSUSE 11.0 installation DVD и в консоли глянул /proc/cpuinfo, free, lspci, lsusb и пр. Был приятно удивлён: проц Core 2 Quad, 2 гига оперативы, винт на 500 гиг, всё железо на матери интеловское. Это обещало установку без геморроя. Задумался: не уж то Acer что-то дельное выпустили? Хаха, щаз.

Поставил систему быстро: снёс все разделы (в том числе и скрытый) и разметил диск: /boot, /, swap, extended, /home. Система встала быстро, без глюков и гемора (благо иксы и десктопманагеры ставить не надо). Понравился новый гламурный дизайн yast.

Ок, после перекомпиляции ядра решил ребутнуться, проверить его работоспособность. А вот фиг. Груб вывалился в консоль. Ну, думаю, консоль — и ладно, ща вручную бутанёмся и поправим. А вот фиг. Груб орёт, что раздел /boot у меня имеет код 0×27, а не 0×83. Задумался. Ну, чего не бывает: может, инсталлер взглючил. Бутанулся опять с DVD, запустил fdisk, прописал вручную код 0×83, записал на хард, замонтировал, отмонтировал, прочитал ещё раз fdisk’ом таблицу: всё ок. Ребутаюсь… Та же херь: код партиции опять стал 0×27. Отмечу, что описалово скрытой партиции с Vista хранится на том же месте. Прошёлся ещё раз fdisk’ом — не помогло. Полез в BIOS: может, там это можно отключить. Не нашёл. Вот скажите, какими уродами нужно быть, чтобы встроить в BIOS код, который прописывает код партиции 0×27 (то есть, скрытого раздела висты)? Если кто знает, как от этого избавиться, подскажите.

Это ладно. Помимо прочего, на компе в BIOS зашита такая интересная фигня, как Intel (C)(R)(TM) Active Management Technology. Подумал, может она гадит. Решил отключить, для чего пришлось прочесть следующий мануал очень сомнительного содержания:

Free Image Hosting at www.ImageShack.us

Free Image Hosting at www.ImageShack.us

Почему сомнительного? Да потому что это называется не иначе как «Настрой троянца на своём компе». Особенно порадовало требование открыть определённые порты в брандмауэре. И вот такие компьютеры будут стоять практически на каждой кафедре и в каждой лаборатории в университете (!). Лично я считаю, что это — пипец.

Ну и ещё один документ на закуску:

Free Image Hosting at www.ImageShack.us

Кстати, ни одного мануала на русском так и не было, что как бэ намекае.

Спросил своих на кафедре, на кого писать заявление об отказе от ОС на компьютере. Сказали, что пока никому. ОК, подождём.

Hand-made синхронизация репозиториев Subversion

Март 29th, 2009

Несмотря на то, что репозиторий ОС XSystem мигрировал ко мне на домашний сервер, всё же хорошо было бы хранить бэкапы на каком-нибудь удалённом сервере.
Для этого я решил воспользоваться уже имеющимся репозиторием subversion на http://sourceforge.net/.

Идея работы такая: раз в сутки мой репозиторий должен синхронизироваться с удалённым репозиторием. При этом, все изменения в одном репозитории должны однозначно отражаться на другом. С версии subversion 1.4 появилась такая тулза, как svnsync, но она для моего случая не подходит: оба репозитория не предоставляют прямого доступа к svnroot.

Поэтому, немного порывшись в гугле, решил прибегнуть к собственному механизму синхронизации. Идея простая: раз в сутки сливается содержимое первого и второго (будем называть source и destination) репозитория. После этого сверяем содержимое source-репозитория с содержимым destination-репозитория: создаём несуществующие каталоги и копируем несуществующие файлы. Файлы, имеющие различные контрольные суммы md5, также перезаписываем. Но это не всё. После того, как мы влили новое файло в локальное дерево destination-репозитория, мы должны удалить из него те файлы, которых уже нет в source-репозитории. Для этого осуществляем обратную сверку снимка destination-репозитория с source-репозиторием и удаляем из него лишние файлы.

В результате всё это было сведено к скрипту на PERL.

#!/usr/bin/perl

use strict;

my @blacklist   =
(
    qr(^\.svn|\/\.svn$),
    qr(^\.{1,2}$|\/\.{1,2}$)
);


my $src_path  = 'xsystem';
my $dst_path  = 'xskernel-sync';
my $svn_user  = '';
my $svn_pass  = '';

# Update repositories
`svn update $src_path`;
`svn update $dst_path`;

# now search files in src_path and compare to dst_path

add_files();
remove_files();

`svn commit $dst_path -m "Synchronization commit" --username $svn_user --password $svn_pass`;

Как видно, работа скрипта достаточно примитивна. Для его работы нужно иметь два рабочих снимка репозитория: source и destination. У меня source-репозиторий находится в каталоге xsystem, а destination — в каталоге dst_path.
Скрипт сначала обновляет снимки репозиториев, затем осуществляет вливание новых файлов в destination-репозиторий при помощи функции add_files(). После этого удаляются устаревшие файлы и каталоги из destination-репозитория функцией remove_files() и производится коммит изменений в destination-репозиторий.

Дело осталось за малым — разобрать функции добавления и удаления файлов и каталогов. Для этого сначала напишем функцию, которая получает md5sum файла:

sub md5sum
{
    my $fname = shift;
    if (open PIPE, "md5sum $fname |")
    {
        my $line = ;
        close PIPE;
        my ($sum) = ($line =~ /^(\w+)\s+/o);
        return $sum;
    }
    return undef;
}

В принципе, ничего нового. Вызывается утилита md5sum и анализируется её вывод.

Также необходимо игнорировать каталоги ".svn", "." и "..", для чего вводится массив @blacklist и пишется функция банинга файлов:

sub ban_file
{
    my $src_file = shift;
    foreach (@blacklist)
    {
        ($src_file =~ $_) and
            return 1;
    }
    return undef;
}

После этого можно спокойно разобрать функцию add_files():


sub add_files
{
    my @directories = ();
    my $curr_dir = '';

    do
    {
        # Открываем каталог
        if (opendir DIRHDL, "$src_path$curr_dir")
        {
            CYCLE: # Читаем содержимое каталога
            while (my $fname = readdir DIRHDL)
            {
                # Баним ненужные файлы
                my $src_file = "$src_path$curr_dir/$fname";
                (ban_file($src_file)) and
                    next CYCLE;

                my $dst_short = "$curr_dir/$fname";
                my $dst_file  = "$dst_path$dst_short";

                # Файл является каталогом?
                if (-d $src_file)
                {
                    # необходимо проверить, что он есть в destination-репозитории
                    unless (-d $dst_file)
                    {
                        # если каталога нет - его нужно создать
                        print "mkdir   $dst_short\n";
                        `mkdir -p $dst_file`;
                        `svn add $dst_file`;
                    }

                    # Запомним каталог для того, чтобы в будущем его просмотреть
                    push @directories, $dst_short;
                }
                else
                {
                    # проверяем, существует ли файл в destination-репозитории
                    unless (-e $dst_file)
                    {
                        # файл не существует, его нужно скопировать и добавить
                        print "add     $dst_short\n";
                        `cp -f $src_file $dst_file`;
                        `svn add $dst_file`;
                    }
                    else
                    {
                        # файл существует, вычисляем md5sum обоих файлов
                        my $sum1 = md5sum($src_file);
                        my $sum2 = md5sum($dst_file);

                        # если суммы не совпадают - заменяем файл новым
                        if ($sum1 ne $sum2)
                        {
                            print "replace $dst_short\n";
                            `cp -f $src_file $dst_file`;
                        }
                    }
                }
            }
        }
        else
        {
            print "Can't open dir $src_path$curr_dir\n";
        }

        # закрываем каталог и получаем следующий каталог, который следует обработать
        closedir DIRHDL;
        $curr_dir = shift @directories;
    }
    while (defined $curr_dir); # крутимся, пока в списке присутствуют обрабатываемые каталоги.
}

При удалении функция будет очень похожа, только теперь надо осуществлять поиск файлов в destination-репозитории и смотреть, есть ли они в source-репозитории:

sub remove_files
{
    my @directories = ();
    my $curr_dir = '';

    do
    {
        # опять же, открываем каталог destination-репозитория
        if (opendir DIRHDL, "$dst_path$curr_dir")
        {
            CYCLE: # читаем файлы
            while (my $fname = readdir DIRHDL)
            {
                # баним недопустимые diren'ы
                my $src_file = "$dst_path$curr_dir/$fname";
                (ban_file($src_file))
                    and next CYCLE;

                my $src_short = "$curr_dir/$fname";
                my $dst_file  = "$src_path$src_short";

                # проверяем, является ли это каталогом
                if (-d $src_file)
                {
                    # проверяем, существует ли этот каталог в source-репозитории
                    unless (-d $dst_file)
                    {
                        # каталога нет - удаляем его из destination-репозитория
                        print "rmdir   $src_short\n";
                        `svn delete $src_file`;
                    }
                    else
                    {
                        # каталог существует, запоминаем его для дальнейшей обработки
                        push @directories, $src_short;
                    }
                }
                else
                {
                    # Это обычный файл, проверяем, есть ли он в source-репозитории
                    unless (-e $dst_file)
                    {
                        # Файла нет, удаляем его из destination-репозитория
                        print "unlink  $src_short\n";
                        `svn delete $src_file`;
                    }
                }
            }
        }
        else
        {
            print "Can't open dir $dst_path$curr_dir\n";
        }

        # Закрываем каталог, получаем следующий
        closedir DIRHDL;
        $curr_dir = shift @directories;
    }
    while (defined $curr_dir);
}

Недостаток этой тулзы один: если файл был перемещён, то он будет распознан как новый файл. Хотя, я не думаю, что файлы и каталоги так часто перемещаются в логически корректно построенном дереве проекта.