среда, 16 января 2013 г.

Проблемы, с которыми я столкнулся после обновления Fedora 17 до Fedora 18

У меня установлены MATE и Compiz отсюда. В репозитории пока нет обновленных пакетов для Fedora 18. Это приводит к нескольким проблемам, которые я перечислю в порядке значимости.
  1. Симптом: caja (аналог nautilus в MATE) не может загрузить иконки для файлов (в т.ч. на рабочем столе) и начинает поедать 100% CPU.
    Лечение: удаляем директорию $HOME/.thumbnails и создаем вместо нее символическую ссылку на $HOME/.cache/thumbnails:
    cd
    rm -r .thumbnails/
    ln -s .cache/thumbnails .thumbnails
    
    Если целевая директория $HOME/.cache/thumbnails отсутствует, то создайте ее. Проблема уже исправлена в последних версиях mate-desktop ветки 1.4.

  2. Симптом: команда yum check показывает отсутствующие зависимости для некоторых компонентов MATE, в частности atril-libs и mate-color-manager требуют libtiff.so.3, а mate-note - libpcre.so.0. Эти библиотеки в Fedora 18 были обновлены до новых версий.
    Лечение: просто забить (однако в этом случае придется удалить иконку mate-note с панели MATE).
    Вариант: скачать SRPM файлы соответствующих библиотек из Fedora 17 (например отсюда), установить их с помощью rpm (я обычно делаю это от имени специального пользователя mockbuild):
    rpm -Uvh libtiff-3.9.7-1.fc17.src.rpm
    
    (здесь я привожу пример только для libtiff). Перейти в директорию rpmbuild/SPECS, заменить строку Name: libtiff на Name: libtiff3 и собрать rpm:
    rpmbuild -ba libtiff.spec
    
    Теперь перейти в директорию ../RPMS/<your-arch> и от имени суперпользователя установить новый пакет libtiff3:
    rpm -Uvh libtiff3-3.9.7-1.fc18.R.x86_64.rpm
    
Вообще-то я надеюсь, что данный репозиторий MATE скоро обновится до Fedora 18 и первые две проблемы уйдут.

Теперь более интересная проблема. Сообщение Authentication is required for powering off while other users are logged in и предложение ввести пароль суперпользователя при попытке выключить или перезагрузить компьютер из GDM или пользовательской сессии. Возможно у вас не возникнет этой проблемы, или она будет возникать иногда при попытке выключить компьютер из GDM сразу же после выхода из пользовательской сессии.

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

Итак, по порядку. Как обнаружить причину такой странной и специфичной для Fedora 18 проблемы? Что мы имеем? Мы загрузили компьютер, пытаемся тут же его выключить и получаем сообщение, что мы не одни в системе! Оказывается, в новой Fedora за сессиями пользователей следит systemd, а просмотреть состояние сессий можно с помощью утилиты loginctl. Так и делаем. Переходим в виртуальную консоль, логинимся от имени рута и набираем loginctl list-sessions. На экран выводится
   SESSION        UID USER             SEAT            
        c1          4 lp
Супер! Пользователь lp в системе! Что же он делает?
# loginctl user-status lp
lp (4)
           Since: Tue, 2013-01-15 21:26:02 MSK; 3min 49s ago
           State: active
        Sessions: c1
          CGroup: name=systemd:/user/lp
                  └ c1
                    └ 701 /usr/bin/tprintdaemon 0
Очевидно, это результат запуска системного демона /etc/init.d/tpdaemon, который при старте открывает оболочку для пользователя lp. Как теперь быть? Мигрировать демон на systemd! Здесь я нашел как это сделать. Сначала отключаем демон в init.d:
chkconfig tpdaemon off
service tpdaemon stop
Затем создаем новый сервисный файл для systemd /etc/systemd/system/tprintdaemon.service и записываем в него строки
[Unit]
Description=TurboPrintDaemon

[Service]
Type=forking
ExecStart=/usr/bin/tprintdaemon
Restart=on-abort

[Install]
WantedBy=multi-user.target
Теперь регистрируем и запускаем новый сервис:
systemctl enable tprintdaemon.service
systemctl start tprintdaemon.service
Как это обычно бывает, с первого раза новый подход не принес результата. Выяснилось, что TurboPrint запускает программу turboprint-monitor 0 -hide, которая работает от имени залогинившегося пользователя и действует как демон, что не позволяет systemd и loginctl считать, что этот пользователь успешно разлогинился. Выход из ситуации: убивать turboprint-monitor при выходе пользователя из графической оболочки, благо эта программа запускается при каждом новом логине заново. Как это сделать? Я использую в качестве дисплейного менеджера GDM. В GDM есть прекрасное место, где можно определить действия при выходе из пользовательской сессии: это файл /etc/gdm/PostSession/Default. Вот строки, которые я добавил в этот файл для принудительного завершения turboprint-monitor, а также pulseaudio:
for service in pulseaudio turboprint-monitor ; do
  PID=$(loginctl user-status $USER | grep "[0-9]\+\s\+\S*$service" | \
                                     sed 's/^[^0-9]\+\([0-9]\+\).*/\1/')
  [ "$?" == "0" ] && kill $PID
done
Зачем здесь pulseaudio? Оказывается, он большой тормоз и выходит по завершении пользовательской сессии не сразу. Это приводит к задержке очистки пользовательской сессии, и соответственно возможен сценарий, когда пользователь выходит из графической сессии и, сразу пытаясь выключить компьютер из GDM, получает то же невнятное сообщение о присутствии других пользователей с предложением ввести пароль рута.

В общем, systemd в роли менеджера сессий вызывает впечатление пока еще сырого продукта.

Update. Репозиторий MATE обновился! Инструкция по установке здесь. Соответственно проблема с зависимостями и mate-note уходит. Однако автор решил не обновлять сами пакеты до выхода стабильной ветки MATE 1.6, которая ожидается в марте этого года, а это значит, что проблема с caja скорее всего не исправлена. Кроме того, после обновления я заметил, что цвет текста в верхней панели стал почти полностью сливаться с фоном панели, поэтому пришлось добавить в файл $HOME/.gtkrc-2.0 такие строки:
style "my_color"
{
        fg[NORMAL] = "#AAAAAA"
}
widget "*PanelWidget*" style "my_color"
widget "*PanelApplet*" style "my_color"
Кроме того, я убрал с панели стандартный индикатор раскладки клавиатуры, так как непонятно, как изменить его цвет, да и к тому же он мне не нужен, так как я использую gxneur:
mateconftool-2 -s /desktop/mate/peripherals/keyboard/general/disable_indicator -t bool true

Update 2. Еще одна проблема. Программа epstopdf стала генерировать пустые pdf с такими сообщениями об ошибке:
Error: /invalidfont in /findfont
Operand stack:
   Times-Roman
Execution stack:
   ...
Dictionary stack:
   ...
Current allocation mode is local
Last OS error: Not a directory
GPL Ghostscript 9.06: Unrecoverable error, exit code 1
Выяснилось, что это из-за того, что я установил пакет fontconfig-infinality, который банит шрифты Type 1 в /etc/fonts/infinality/infinality.conf. Чтобы восстановить работу epstopdf, следует закомментировать в этом файле следующие строки:
    <selectfont>
        <rejectfont>
            <pattern>
                <patelt name="fontformat" >
                    <string>Type 1</string>
                </patelt>
            </pattern>
        </rejectfont>
    </selectfont>
Очевидно, данная проблема связана не с обновлением Fedora, а, собственно, с установкой fontconfig-infinality.
 
Update 3. Автор репозитория MATE таки отказался поддерживать свой репозиторий для Fedora 18. То, что он выложил раньше, оказалось его ошибкой (см. здесь). Так что теперь у нас два варианта (напомню, что моим приоритетом является сохранение Compiz в системе, а этот пакет предоставляется только данным репозиторием).
  1. Оставить все как есть. В этом случае все пакеты из старого репозитория MATE, включая Compiz, останутся в системе и будут работать. Если вы не успели проапгрейдить MATE из ошибочного репозитория, то останутся проблемы с зависимостями (libtiff.so.3 и libpcre.so.0), и, вполне возможно, в дальнейшем появятся новые неудовлетворенные зависимости, так как вы, очевидно, не сможете проапгрейдить пакеты MATE из более несуществующего репозитория.

  2. Выбрать и снести выборочные пакеты из старого репозитория MATE c помощью rpm -evh --nodeps. При этом не следует удалять пакеты Compiz, поскольку автор репозитория обещал добавить их в новый репозиторий mate-desktop-extra через неделю, и пока их там нет! Собственно для этого и нужен флаг --nodeps для rpm, так как пакеты Compiz зависят от MATE. После удаления старых пакетов MATE нужно установить новые пакеты командой
    yum groupinstall MATE-desktop
    
    и добавить пакеты из репозитория mate-desktop-extra:
    yum install https://dl.dropbox.com/u/105479527/Mate-Desktop/fedora-release-extra-18/mate-desktop-fedora/noarch/mate-desktop-extra-release-18-1.fc18.noarch.rpm
    yum groupinstall mate-desktop-extra
    
    Минус этого подхода в сложности выбора нужных пакетов для удаления и необходимости заново настраивать внешний вид десктопа. Плюсы: отсутствие проблем с зависимостями и постоянные обновления пакетов из стандартного репозитория Fedora.
Лично я воспользовался вторым способом. Все работает, но есть и регрессии, связанные с верхней панелью: по какой-то причине отсутствует апплет для датчиков температуры, нет больше mintmenu (оно якобы несовместимо с новой версией панели), нет апплета переключения пользователей, погодный апплет почему-то выводит текст Неизвестно.
 
Update 4. До Fedora 18 я пользовался этим репозиторием для texlive. Теперь все пакеты из последнего texlive есть в стандартном репозитории, поэтому сносим все пакеты из старого репозитория и устанавливаем их из нового:
rpm -qa tex-* texlive-* | xargs yum -y remove
yum install texlive texlive-collection-langcyrillic texlive-disser texlive-mhchem texlive-braket texlive-feynmf texlive-hepparticles texlive-hepnames texlive-subfigure texlive-wrapfig texlive-gost texlive-bibtexu texlive-helvetic texlive-epstopdf texlive-metapost texlive-minted texlive-latexmk texlive-cm-super
В списке на установку обязательными являются только два пакета: texlive и texlive-collection-langcyrillic. Остальные пакеты из списка не устанавливаются по умолчанию, но я их использую. Кстати, проблему с переносами русских слов, о которой я писал здесь, в новом репозитории кажется уже решили.

четверг, 10 января 2013 г.

A perl script for gathering blogger stats and showing it on a terminal

I decided to experiment and write this post in English. Recently I uploaded a small perl script bloggerstats on the github (see here). The script can help to gather statistics of a blog hosted on the blogger.com. The stats can be dumped on a terminal or redirected to a file. As well pretty charts in PNG format can be created. See images below.


The usage of the script is shown with -h or --help option. The script requires several mandatory and optional perl modules: JSON, URI::Escape, Encode, Data::Dumper (for dumping received JSON data in debug mode), Text::TabularView (for printing result in pretty tables), Chart::Bars and Time::Local (for making charts). All modules are either normally shipped with perl distributions or available in the system repository (I found all of them in my standard Fedora 17 rpm repository). The script also requires several external programs: sed, curl (for network communication with blogger.com) and ngrep (for sniffing sensitive data required by blogger.com, see below).

To start using it one should provide basic configuration settings in file $HOME/.bloggerstatrc. I put a template file bloggerstatrc.tmpl in the github repository to start with. Here is its content:
$blogID      = 'put-here-your-blog-id';
$bloghost    = 'blogger.com';

$statsurl    = "http://www.$bloghost/blogger_rpc?blogID=$blogID";

$start_year  = 2010;
$start_month = 5;       # months start from 1, so January is 1

# AUTOGENERATED (do not delete this line!)
Actually .bloggerstatrc is an ordinary perl source file and is to be sourced from bloggerstats, so you can put there any statements that perl can compile, but those 5 variables defined in this template are mandatory ones. Of course you have to substitute your real blogID instead put-here-your-blog-id (this is the value of the parameter blogID in any related HTTP GET request to blogger.com: you can find it in the address line in your browser). You also have to substitute proper values of $start_year and $start_month: they must correspond to the first bin of the all-time visits chart in your blog. The line with comment starting with AUTOGENERATED must reside below your regular settings: it is used by the sniffer for updating other sensitive variables (cookies, headers and xsrf token) below it. Every time you run bloggerstats -w all content below this line gets removed!

Why do I say here about sniffer? Unfortunately blogger.com API seems to be closed at the moment. The only thing known is that it uses GWT (Google Web Toolkit) and JSON for sending data to the client. GWT produces very large obfuscated Javascript code which finally creates xsrf token and sends it to the server. The algorithm that creates it is unknown. The generated token is valid through approximately 24 hours. Besides the token blogger.com checks for sessionID cookies (which can also become invalid but not so often as the token) and GWT related HTTP headers. All these data are collected by the sniffer and put below the comment line starting with AUTOGENERATED in .bloggerstatsrc. As soon as sniffing network interfaces requires root privileges the script must possess them. To achieve this login as root, open some new sudoers file (say /etc/sudoers.d/users) with visudo and put there following lines
Cmnd_Alias       NETTASKS = /usr/sbin/ngrep
<your-login-id>  ALL = NOPASSWD: NETTASKS
where <your-login-id> is your system login name. Word NOPASSWD in the second line is important: it prompts sudo do not ask password when starting ngrep.

So now that you configured basic parameters in .bloggerstatsrc you may want to launch the sniffer by running bloggerstatrc -w in a terminal (it will wait until stats request is sent to blogger.com via a browser), open your blogger.com stats page in a browser or just refresh it. The sniffer must exit (though it may fail to exit at very heavy network load: refresh stats page several times in this case) and now bloggerstats is ready to gather blogger statistics. As soon as saved xsrf token or cookies become invalid (in one day or so) you will see errors, running the sniffer once again will bring bloggerstats back to life.

Finally I want to show settings for tabular highlights as seen on the first image above (look here about hl and Term::Highlight). File .hlrc:
snippet bstats  -b -82 '^(?:\+-+)+\+$' '^\|\s+' '\s+\|$' \
                '\s+\|\s+(?=.*\s+\|$)'-67 \
                '(?<=^\|)\s+(?:Overview|Page|Keyword|Site|URL|Country)\s+' \
                '(?<=^\|)\s+(?:Browser|OS)\s+' -215 '(?<=\|)\s+\d+\s+(?=\|$)' \
                -rb -48 '(?<=^\|)\s+Today\s+(?=\|)'
File .hl_functions:
function bloggerstats
{
    `env which bloggerstats` $@ | hl -sbstats
}
Vielleicht schreibe ich nächstes Mal auf Deutsch :)