Обновление на openSUSE 11.4

Обновляюсь с openSUSE 11.3 на openSUSE 11.4. zypper dup сначала радостно снес у меня пакет liblzma0-4.999.9beta, а через мгновение rpm выяснил, что не может почему-то запуститься без lzma0, жалобно смотрел на меня и говорил:
rpm: error while loading shared libraries: liblzma.so.0: cannot open shared object file: No such file or directory
Тут все бы и закончилось, если бы я не скачал и не подсунул нужную библиотеку ему.

upd: тут в комментариях умные люди сделали правильные оргвыводы. zypper addlock liblzma0, либо обновляться с http-репозитория, а не с DVD.

openSUSE Build Service: kvm с поддержкой virtio

Инструкция по созданию образа initrd с поддержкой virtio. В файле
/etc/sysconfig/obs-worker должно быть указано, где какие образы искать рабочим(а то сами они могут не то найти), кроме того, там указана файловая система, которую вы желаете использовать для виртуальных дисков (у меня по умолчанию был ext3). По идее, файловая система важна только чтобы initrd смог потом её смонтировать.

rootfstype="ext4" mkinitrd -d /dev/null -m "binfmt_misc virtio_pci virtio_blk" -k /boot/vmlinuz -i /boot/initrd-virtio -S

Создаст специальный initrd, который потом можно скормить сборщикам. Важно указать rootfstype, иначе mkinitrd начинает пытаться определить тип файловой системы у /dev/null и ругается.

upd: В скором времени восприятие /dev/null было окончательно починено (поломано). Несмотря на то, что скрипт build до сих пор содержит напоминание о ключе -d /dev/null, эта опция больше не работает. Самым простым способом оказалось копирование /lib/mkinitrd куда-нибудь в сторону и наглое исправление файла scripts/setup-storage.sh:
@@ -331,9 +331,10 @@
             fstype=nfs
             ;;
         /dev/*)
-            if [ ! -e "$dev" ]; then
-                error 1 "$name device ($dev) not found"
-            fi
+       fstype=$rootfstype
             ;;
         *://*) # URL type
             fstype=${dev%%://*}

После чего следует использовать команду:

rootfstype="ext4" mkinitrd -d /dev/vda -m "binfmt_misc virtio_pci virtio_blk" -k /boot/vmlinuz -i /boot/initrd-virtio -S -l /path/to/lib/mkinitrd

VirtualBox 4.0 USB

С выпуском четвертой версии виртуальной машины VirtualBox среди прочих изменений в стала доступна возможность подключения USB-устройств в гостевой ОС. Вообще говоря, такая возможность была раньше и в проприетарной версии.

При попытке воспользоваться этой возможностью может обнаружиться примерно такой симптом: в списке устройств все устройства подключенные к физической машине есть, но они "неактивные" и галочки не горят. Соответственно, в гостевой ОС их не видно.

Существуют инструкции, в том числе и на официальном сайте VirtualBox, где объясняется как монтировать /proc/bus/usb, чтобы все заработало. Так вот, эта инструкция только для относительно старых ядер, например в openSUSE 11.2 монтировать ничего не нужно.

Для активации поддержки USB следует: во-первых, убедиться что существует группа vboxusers и нужные пользователи включены в неё, во-вторых, открыть /etc/udev/rules.d/60-vboxdrv.rules и активировать там соответствующие настройки:

KERNEL=="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="root", MODE="0600"
#these two lines give access permission to vboxusers to properly work with usb nodes, this could be security risk (bnc#664520) !!
SUBSYSTEM=="usb_device", ATTR{devnum}=="?*", ATTR{busnum}=="?*",NAME="vboxusb/$attr{busnum}/$attr{devnum}", GROUP="vboxusers"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{devnum}=="?*", ATTR{busnum}=="?*",NAME="vboxusb/$attr{busnum}/$attr{devnum}", GROUP="vboxusers"

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

python и ленивые(lazy) атрибуты

В интернете куча примеров как сделать ленивые атрибуты для класса, чтобы не искать, оставлю здесь еще один пример:

class lazy(object):
        def __init__(self, function):
                self._function = function

        def __get__(self, instance, owner = None):
                if instance == None:
                        return self
                val = self._function(instance)
                setattr(instance, self._function.func_name, val)
                return val

class line(object):
        def __init__(self, line = None):
                self._line = line

        @lazy
        def items(self):
                return self._line.split()

Объяснение: items, коль скоро он декорируется, становится объектом класса lazy, и начинает восприниматься как дескриптор(descriptor). Поэтому __get__, __set__ и __delete__ могут быть определены у класса lazy. Конкретная реализация __get__ вычисляет значение функции и привязывает объект с результатом в качестве атрибута вместо себя на свое имя. Значит, последующие обращения к items — уже не вызов функции, а просто операции со списком, что вернулся при первом вызове.

boost.python

Для сборки чего-либо с использованием boost.python его авторы рекомендуют использовать bjam, угрожая при этом в документации, что если что-то и отвалится, то исключительно по причине не использования оного.

Если не использовать bjam, то существует подсказка для выбора правильных параметров для компиляции и линковки: идем в ./libs/python/example/quickstart и просим bjam -n (т.е. распечатать команды вместо того, чтобы их запускать)

Кроме того, у меня работал вот такой Makefile:
all: test1.so

test1.so: test1.o
 $(CXX) -shared $< -o $@ -lboost_python

test1.o: test1.cpp
 $(CXX) `python-config --includes` -fPIC $< -c -o $@

Внешние скрипты и Django

Когда в следующий раз понадобится запускать какой-то внешний скрипт для облегчения пакетного менеджмента сайтов, пригодится этот пример:

import os
import sys

# укажем путь к нашему django-сайту
sys.path.append('/var/www/mydjango')

# укажем какие настройки следует использовать
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

# импортируем модели
from myapp import models

# используем

Альтернативный вариант, который не предполагает никаких дополнительных изменений в самом скрипте. Просто запустим наш скрипт, установив нужное окружение:

PYTHONPATH=/var/www/mydjango DJANGO_SETTINGS_MODULE=settings python my-script.py

openSUSE Build Service 2.0.5

Наконец переехал у себя с OBS 1.7 на 2.0. OBS — это, пожалуй, единственное ПО, которое я ставлю из пакета, делаю как в инструкции, и... и все падает с какими-то не информативными странными ошибками.

Начать следует с того, что, насколько я понял, эта штука теперь научилась работать с gpg2, поэтому gpg 1.4.5 со специальным патчем "files_are_digests" можно выкинуть. Не забыв при этом подправить путь к gpg в /etc/sign.conf

Порадовало, что наконец в пакет добавили конфиги для logrotate, теперь логи не вырастают до невиданных размеров.

Теперь более интересное. В связи с тем, что рабочие научились самостоятельно создавать себе образы дисков, в /etc/sysconfig/obs-worker добавлено очень много новых опций. В нем же можно изменить рабочую директорию (теперь по умолчанию /var/cache/obs/worker), размеры образов, количество памяти для виртуальной машины и указать её тип. В нем же мне пришлось обратить пристальное внимание на OBS_VM_KERNEL и OBS_VM_INITRD, у меня ничего не заработало пока я их не исправил:
OBS_VM_KERNEL="/boot/vmlinuz"
OBS_VM_INITRD="/boot/initrd-virtio"
Дело в том, что я предпочитаю использовать build с KVM. И, к сожалению, build не смог самостоятельно найти нужные образы для загрузки без явного указания этих параметров. Кстати, файл /boot/initrd-virtio (initrd с поддержкой virtio) делает сам скрипт build, так что не надо удивляться откуда он взялся.