вторник, 17 февраля 2009 г.

ALT Linux 4.1 Desktop Lite - неофициальная сборка

Время от времени в community@lists.altlinux.ru спрашивают: а где бы раздобыть ALT Linux 4.1 Desktop Lite, который до релиза, как известно, не дожил :(

Поскольку я собирал для себя нечто подобное, но с другим дизайном и с другими дефолтами, и лучше поздно, чем никогда, выкладываю пересобранные на сегодняшнем branch/4.1 cd-образы:
Инсталлятор от официального не отличается ничем, свежеустановленная система выглядит так:


Если кому-то вдруг захочется это собрать, профиль можно взять здесь. Планы по сборке аналогичного дистрибутива на branch/5.0 есть, но если кто-нибудь меня опередит, я буду только рад :)

воскресенье, 15 февраля 2009 г.

Практическое введение в Git

Возможно, я плохо искал, но простого пошагового введения в Git на русском для тех разработчиков и админов, которые кое-как научились использовать CVS или SVN, до сих пор нет. Много полезных материалов и ссылок можно найти на ALT Linux Wiki, однако значительная их часть содержит альтовскую дистрибутивостроительную специфику или, наоборот, несколько далека от практических задач. Я попытаюсь описать один из типичных сценариев использования Git без привязки к каким-либо задачам и без излишних подробностей - за ними лучше сразу идти в Git User's Manual.

Итак, основная идея Git, как и любой распределенной SCM, заключается в том, что мы имеем дело с локальными коммитами в индивидуальных репозитариях разработчиков и с мехнизмами обмена коммитами между репозитариями. Главное преимущество - гибкость (можно вести локальные бранчи с локальными коммитами, не забивая основной репозитарий результатами неудачных или удачных экспериментов), обратная сторона - некоторое увеличение сложности взаимодействия по сравнению с централизованными SCM.

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

Устанавливаем все необходимое и заводим на сервере центральный репозитарий:
# apt-get install git-core
# mkdir /home/repo/alpha.git
# cd /home/repo/alpha.git
# git init --bare --shared=true
Работать с ним будем по ssh, поэтому создаем для разработчиков учетные записи и добавляем их в группу, во владение которой передаем репозитарий:
# useradd -d /var/empty/ -s /usr/bin/git-shell user1
# useradd -d /var/empty/ -s /usr/bin/git-shell user2
# groupadd alpha
# usermod -G alpha user1
# usermod -G alpha user2
# chown -R root:alpha /home/repo/alpha.git
Теперь один из разработчиков может создать локальный репозитарий и сделать в нем несколько коммитов:
[user1@workstation1 ~]$ mkdir alpha
[user1@workstation1 ~]$ cd alpha
[user1@workstation1 alpha]$ git init
[user1@workstation1 alpha]$ git config user.name 'User 1'
[user1@workstation1 alpha]$ git config user.email 'user1@workstation1'
[user1@workstation1 alpha]$ echo 'line 1' > file
[user1@workstation1 alpha]$ git add .
[user1@workstation1 alpha]$ git commit -a -m 'add line 1'
[user1@workstation1 alpha]$ echo 'line 2' >> file
[user1@workstation1 alpha]$ git commit -a -m 'add line 2'
Каждый коммит принадлежит одному или нескольким бранчам. Для первого коммита автоматически создается бранч с именем master, в него же по умолчанию попадают следующие коммиты.

Несколько полезных команд:
  • git branch - показать список бранчей, выделив текущий, создать, удалить или переименовать бранч
  • git status - показать текущее состояние рабочей копии (какие новые файлы появились, а какие были удалены, что закоммитили, а что нет, и т.д.)
  • git log - показать историю коммитов, каждый из которых идентифицируется с помощью хеша sha1
  • git show - показать подробности последнего коммита или любого коммита по его хешу
  • git diff - показать разницу между последним коммитом и рабочей копией или между коммитами
Теперь подготовим наш репозитарий к отгрузке коммитов в центральный репозитарий на сервере:
[user1@workstation1 alpha]$ git remote add origin user1@gitserver:/home/repo/alpha.git
И отправим туда коммиты, принадлежащие локальному бранчу master - они попадут в удаленный бранч с таким же именем:
[user1@workstation1 alpha]$ git push origin master
В дальнейшем можно будет ограничиться git push, т.к. origin - дефолтное имя удаленного репозитария, а бранч master в нем уже существует. С другой стороны, ничто не мешает явно указывать URL удаленного репозитария и имена локального и удаленного бранчей:
[user1@workstation1 alpha]$ git push user1@gitserver:/home/repo/alpha.git master:master
Для получения коммитов из центрального репозитария в локальный бранч master его нужно было бы создать с параметром --track, однако бранч уже существует, поэтому просто укажем соответствующий ему удаленный бранч в настройках:
$ cat >> .git/config << EOF
> [branch "master"]
>       remote = origin
>       merge = refs/heads/master
> EOF
Получить новые коммиты из центрального репозитария можно так:
[user1@workstation1 alpha]$ git fetch
[user1@workstation1 alpha]$ git merge origin/master
или просто:
[user1@workstation1 alpha]$ git pull
В случае конфликтующих изменений операция merge не будет завершена коммитом - в этом случае нужно будет выполнить git commit самостоятельно после разрешения конфликта.

Разумеется новые коммиты могут появиться в центральном репозитарии только после того, как другой разработчик клонирует его, внесет туда какие-либо изменения и отправит их обратно - при этом настраивать свой репозитарий для взаимодействия с удаленным ему уже не потребуется:
[user2@workstation2 ~]$ git clone user2@gitserver:/home/repo/alpha.git
[user2@workstation2 ~]$ cd alpha/
[user2@workstation2 alpha]$ git config user.name 'User 1'
[user2@workstation2 alpha]$ git config user.email 'user2@workstation2'
[user2@workstation2 alpha]$ echo 'line 3' >> file
[user2@workstation2 alpha]$ git commit -a -m 'add line 3'
[user2@workstation2 alpha]$ git push
Теперь чуть подробнее о том, ради чего все эти мучения - ведь для выполнения аналогичных операций средствами CVS или SVN потребовалось бы меньше операций. Дело в том, что до тех пор, пока мы не отгрузили коммиты в удаленный репозитарий, мы вольны распоряжаться ими как нам вздумается. Например, заведем для экспериментов новый локальный бранч и сделаем в нем еще пару коммитов:
[user1@workstation1 alpha]$ git-checkout -b experimental
[user1@workstation1 alpha]$ echo 'line 4' >> file
[user1@workstation1 alpha]$ git commit -a -m 'add line 4'
[user1@workstation1 alpha]$ echo 'line 5' >> file
[user1@workstation1 alpha]$ git commit -a -m 'add line 5'
Если какие-то коммиты лучше было бы не делать, можно откатиться к любому заданному коммиту, указав его:
  • явно в виде sha1 id - их покажет git log
  • по имени тэга - его можно создать для коммита по его sha1 id с помощью git tag
  • относительно другого коммита - например, последнему коммиту, на который указывает HEAD, предшествует HEAD^:
[user1@workstation1 alpha]$ git reset --hard HEAD^
Также бывают полезны параметр --soft (откатиться, но сохранить содержимое измененных файлов для последующего редактирования) и параметр --amend команды git commit (включить содержимое старого коммита в новый).

Вернемся в бранч master, сделаем в нем еще один коммит и втянем туда результаты экспериментов:
[user1@workstation1 alpha]$ git checkout master
[user1@workstation1 alpha]$ subst '/line 1/iline 0' file
[user1@workstation1 alpha]$ git commit -a -m 'add line 0'
[user1@workstation1 alpha]$ git merge experimental
Вместо операции merge, которая создает общий коммит для бранчей, иногда бывает полезно использовать rebase - эта операция переупорядочивает коммиты для того, чтобы сохранить историю линейной. Очень полезно для изучения истории использовать gitk, gitg или qgit - эти инструменты помогут представить описанное более наглядно.

Разумеется, после того, как мы сделали git push, с историей лучше не забавляться - этим мы сильно осложним жизнь тем, кто уже основывает свои новые коммиты на ней. А вот до git push - сколько угодно :)

понедельник, 2 февраля 2009 г.

Redmine quickstart

Похоже, что изначально не приглянувшийся мне Redmine несколько удобнее Trac:
  • есть приличная русификация
  • есть поддержка подпроектов
  • есть web-интерфейс для управления проектами и правами доступа к ним - прям аж обидно, и зачем я тратил время на Trac appliance?
  • и самое главное - дефолтный дизайн отлично гармонирует с дизайном моего блога :)
В качестве ложки дегтя пока заметил лишь то, что принимать информацию об авторизации от Apache он не умеет, правда умеет LDAP, который уже можно прикрутить к Apache. И опакетить его, к сожалению, так просто не выйдет (updated: поэтому вышло непросто).

Мне пришлось поставить из тарболла:
# apt-get install ruby-rake ruby-stdlibs ruby-activerecord-sqlite3-adapter rubygems
# useradd -d /opt/redmine -s /dev/null redmine
# su - redmine -s /bin/bash
$ wget http://rubyforge.org/frs/download.php/49319/redmine-0.8.0.tar.gz
$ tar -zxf redmine-0.8.0.tar.gz 
$ cd redmine-0.8.0
$ cat > config/database.yml << EOF
> production:
>   adapter: sqlite3
>   dbfile: db/production.db
> EOF
$ rake db:migrate RAILS_ENV="production"
$ rake redmine:load_default_data RAILS_ENV="production"
$ ruby script/server -e production
Теперь подключаемся к http://server:3000/ и логинимся под именем admin с таким же точно паролем. Несмотря на грозные предупреждения в руководстве по установке с более новыми, нежели указано, версиями ruby и sqlite вроде бы все работает.

четверг, 29 января 2009 г.

Trac appliance

И все-таки быстрый запуск Trac оказывается не слишком быстрым, а результат - не слишком удобным в сопровождении, особенно когда совместно с Trac предполагается использовать систему управления версиями. Более удобный use case представляется для меня сейчас таким:
  • N проектов - каждый представляет из себя проект Trac и, возможно, настроенный для использования с ним репозитарий Git или Subversion
  • M пользователей - каждый имеет полный доступ к некоторым проектам (т.е. может работать в Trac и коммитить в репозитарий), а к некоторым не имеет вовсе.
Проекты/пользователи должны создаваться/удаляться одной командой, для разрешения/запрета доступа пользователя к проекту также должно быть достаточно одной команды.

Проблема заключается в выборе технологии авторизации и аутентификации, которые позволили бы реализовать описанную схему. Для standalone версий Trac, Git и Subversion ведение единой базы данных пользователей и прав доступа к проектам невозможно, поэтому придется задействовать Apache и его средства управления доступом - соответственно репозитарии Git и Subversion будут доступны по протоколу WebDAV. При этом никто не мешает при необходимости использовать более гибкие настройки прав доступа внутри проектов средствами самих Trac и Subversion.

Готовое решение доступно в виде основного пакета appliance-trac и дополнительных appliance-trac-scm-git и appliance-trac-scm-svn, собираемых из одноименного репозитария. Устанавливаем требуемое штатным для ALT Linux образом:
trac-scm-git
Создаем проект (указываем имя и тип репозитария - если последним параметром будет что-то отличное от git или svn, то репозитарий просто не будет создан):
# appliance-trac-create alpha git
Средствами Apache создаем пользователя:
# htpasswd2 -b /var/www/appliance-trac/passwd user userpwd
Включаем его в соответствующую группу Apache, имя которой соответствует имени проекта:
# vim /var/www/appliance-trac/group
При необходимости пользователя можно сделать администратором Trac:
# trac-admin /var/www/appliance-trac/env/alpha permission add user TRAC_ADMIN
Теперь пользователь user может работать с проектом через web-интерфейс по ссылке http://server//appliance-trac/env/alpha и напрямую с репозитарием:
$ cat > ~/.netrc << EOF
> machine server
> login user
> password userpwd
> EOF
$ git-clone http://server/appliance-trac/scm/git/alpha.git
$ cd alpha/
$ echo "new line" >> README 
$ git commit -a -m 'new commit'
$ git-http-push http://server/appliance-trac/scm/git/alpha.git heads/master
После того, как проект стал ненужным, его можно удалить:
# appliance-trac-drop alpha git

суббота, 10 января 2009 г.

Trac quickstart

Вместе с совсем уж примитивными wiki-движками бывают также полезны интегрированные системы с wiki, багтрекером, web-интерфейсом к какой-нибудь системе управления версиями и прочими вкусностями - и среди них, как одну из самых простых в установке и в эксплуатации, можно выделить Trac.

После установки и запуска штатным для ALT Linux образом:
# apt-get install trac
# service trac start
Trac готов к обслуживанию проектов, размещенных в каталоге /var/lib/trac, однако хотя бы один проект еще нужно создать:
# su - trac -s /bin/sh
$ trac-admin alpha initenv alpha sqlite:db/trac.db "" ""
$ vim alpha/conf/trac.ini # edit [header_logo] and [project] sections
После этого проект будет доступен на чтение всем желающим по ссылке http://localhost:8000/alpha. Для создания и редактирования багов и wiki-страниц необходимо авторизоваться, а для этого сначала создать пользователей следующим образом:
$ trac-passwd -u user -p usrpwd >> /etc/trac/passwd
Для полного управления проектом нужно выдать пользователю user соответствующие права:
$ trac-admin alpha permission add user TRAC_ADMIN
Такая схема разграничения прав доступа удобна для свободных проектов. Для проектов, процесс работы над которыми не должен быть публично доступным, необходима другая схема: как минимум, у пользователя anonymous необходимо изъять все права и явно выдать их группе authenticated. В этом случае все авторизовавшиеся пользователи будут иметь доступ ко все проектам, а это тоже не всегда оправдано. Для того, чтобы можно было ограничить права на уровне отдельных проектов, потребуется также изъять все права у группы authenticated, и передать их отдельной группе, а затем включать требуемых пользователей в эту группу:
$ trac-restrict-env alpha developers
$ trac-admin alpha permission add user developers
Конечно, возможна и более тонкая настройка прав доступа - но об этом подробно написано в документации Trac

вторник, 30 декабря 2008 г.

Lightweight wiki engine

У всех популярных wiki-движков есть один существенный недостаток - они предлагают редактировать контент с помощью браузера. Этот недостаток давно и успешно лечится, однако осадок остается. Действительно, зачем все эти извращения в тех случаях, когда список авторов ограничен и все они имеют shell-доступ к серверу, на котором и живет wiki engine? Пусть редактируют вволю с помощью своего любимого текстового редактора (заодно и какую-нибудь систему управления версиями можно прикрутить), а wiki engine пусть всего лишь отдает текст, отформатированный в html.

Концепт такого движка в виде автономного http-сервера можно можно посмотреть здесь.

вторник, 25 ноября 2008 г.

ALTSP inside OpenVZ VE

Требуется обеспечить всем необходимым (доступ в интернет, почта, офисные приложения и учетное ПО) небольшой офис, в котором имеется один приличный сервер и десяток бездисковых рабочих станций. Задача прекрасно решается средствами ALTSP, однако есть одна проблема - очень уж неудобно держать на одном хосте офис, почтовый сервер, прокси-сервер и т.д. Решение - OpenVZ, возможно, с размазыванием функциональности ALTSP по разным VE.

Первый вопрос, на который следует ответить: будем ли мы использовать venet, veth или вообще проброс физических интерфейсов в VE. Первый вариант, конечно, bit faster and more efficient, но не умеет броадкастов, а потому всю инфраструктуру, необходимую для загрузки бездисковых клиентов придется разместить в HN. В дальнейшем предполагаем, что используется OpenVZ в ALT Linux Lite 4.0 c виртуальной сетью 192.168.0.0/24 и физической сетью 192.168.1.0/24 - в последней и будут размещены бездисковые клиенты.

Настраиваем загрузку клиентов по TFTP:
# apt-get install dnsmasq

# chkconfig dnsmasq on

# cat /dev/null > /etc/sysconfig/dnsmasq

# cat > /etc/dnsmasq.conf <<END
bind-interfaces
interface=lo
interface=lan
resolv-file=/etc/resolv.conf.dnsmasq
strict-order
expand-hosts
domain=local
dhcp-range=192.168.1.10,192.168.1.50
enable-tftp
tftp-root=/diskless/altsp/boot/i586
dhcp-boot=pxelinux.0
END

# cat > /etc/resolv.conf.dnsmasq <<END
nameserver ${NAMESERVER}
END

# cat > /etc/resolv.conf <<END
nameserver 127.0.0.1
search local
END

# mkdir -p /diskless/altsp/boot/i586/pxelinux.cfg

# cat > /diskless/altsp/boot/i586/pxelinux.cfg/default <<END
DEFAULT vmlinuz ro initrd=initrd.img root=/dev/nfs nfsroot=/diskless/altsp/root/i586,udp ip=dhcp
END

# service dnsmasq start
В /diskless/altsp/boot/i586 нужно положить vmlinuz, initrd.img и pxelinux.0 из уже существующей инсталляции ALTSP (см. каталог /var/lib/tftpboot/ltsp/i586/) - увы, автономного инструмента для сборки пока нет :(

Уже на этом этапе загрузка бездисковых клиентов начнется, но остановится на монтировании корневой файловой системы. Настроим раздачу корня по NFS:
# apt-get install unfs3

# chkconfig nfs on
# chkconfig portmap on

# cat > /etc/exports <<END
/diskless/altsp/root/i586 (ro,no_root_squash)
END

# service portmap start
# service nfs start
В /diskless/altsp/root/i586 тоже нужно положить каталог /var/lib/ltsp/i586 из существующей инсталляции ALTSP.

Также включим поддержку сетевого свопа на случай непредвиденного расхода памяти на клиентах:
# apt-get install ltspswapd
# chkconfig ltspswapd on
# service ltspswapd start
Теперь бездисковые клиенты смогут полностью загрузиться и обратиться по XDMCP к тому же серверу, с которого загрузились, но безуспешно: никакого XDMCP там нет и не предполагается. Сначала укажем адрес сервера XDMCP:
# cat >> /diskless/altsp/root/i586/etc/lts.conf <<END
XDM_SERVER=192.168.0.101
END
Затем создадим соответствующий виртуальный сервер с помощью скрипта-обертки, описанного ранее:
# create-ve.sh 101 desktop 4.1 i586
Установим в него все необходимое:
# vzctl start desktop
# vzctl enter desktop

# cat > /etc/sysconfig/i18n <<END
LANG=ru_RU.UTF-8
SUPPORTED=ru_RU
END

# cat > /etc/X11/xinit/Xkbmap <<END
-layout us,ru
-option grp:ctrl_shift_toggle
-variant ,winkeys
END

# apt-get install gdm gdm-theme-altlinux xfce4-minimal xfce-mcs-plugins xfce-settings-simple icon-theme-hicolor xterm Thunar leafpad firefox-ru fonts-ttf-ms

# subst 's/happygnome-list/altlinux/' /etc/X11/gdm/custom.conf
# subst 's/Greeter/RemoteGreeter/' /etc/X11/gdm/custom.conf
# subst '/\[greeter\]/aGraphicalThemedColor=#90a8ca' /etc/X11/gdm/custom.conf
# subst '/\[xdmcp\]/aEnable=true' /etc/X11/gdm/custom.conf
# subst 's/id:3:initdefault:/id:5:initdefault:/' /etc/inittab

# exit

# vzctl restart desktop
И вот теперь бездисковые рабочие станции должны загрузиться и показать приглашение GDM.