15 марта 2009 г.

Архивирование системы или бекап в debian linux

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

dmpfile=backup.tar.bz2
srcdir=/
trgdir=/share
cd $trgdir && tar -cfj $dmpfile --exclude-from=/exclude_back $srcdir

Скрипт переходит в директорию куда надо сохранить архив, и выполняет tar.

--exclude-from - берем список исключений из файла в корне (сам скрипт тоже в корне)

# cat exclude_back
/proc
/mnt
/var/run
/dev
/sys
/home/repo
/share

Последние две - мои директории.

11 марта 2009 г.

Контекстные процессоры Django

Как пишет django book

Для обработки шаблона вам необходим контекст. Обычно это экземпляр django.template.Context, но в поставку Django также входит специальный подкласс — django.template.RequestContext, который работает немного иначе. Класс RequestContext по умолчанию добавляет группу переменных в контекст шаблона - такие как объект HttpRequest или информацию о текущем пользователе.


Класс RequestContext и контекстные процессоры были созданы для решения этой задачи. Контекстные процессоры позволяют вам указывать ряд переменных, которые будут устанавливаться автоматически для каждого контекста, без необходимости их указания в каждом вызове render_to_response(). Надо лишь использовать RequestContext вместо Context при обработке шаблона.


То есть, собственно говоря, для чего на нужны контекстные процессоры?
Контекстный процессор принимает объект HttpRequest и возвращает словарь переменных для его последующего использования в контексте шаблона.
То есть, для поставленной перед собой задачи - вывод дополнительной информации в любых шаблонах он справляется.

В django книге описано, как создавать свои глобальные процессоры.

Есть еще варианты - http://softwaremaniacs.org/forum/django/1439/

3 марта 2009 г.

Django. Валидация формсетов. Часть вторая

При использовании двух формсетов в одном виде возникает следующая проблема валидации:
1. Валидация формсета проходит следующим образом:
а)Валидируются все формы, входящие в рамки:
self._total_form_count = self.management_form.cleaned_data[TOTAL_FORM_COUNT]
б)экстра-формы, в которых нет вообще никаких данных игнорируются.
2. В связи с синхронным использованием двух формсетов может возникнуть следующая проблема:

У одного формсета валидируются, например, 1,2 и 5 форма, а у другого только 1,2, в связи с тем что у второго формсета 5 форма пустая.

Вот эту проблему и попытаемся сегодня решить.

Начало функции, отвечающей за валидацию вормы (валидация формсетов - это просто валидация каждой формы в формсете)

208 def full_clean(self):
209 """
210 Cleans all of self.data and populates self._errors and
211 self.cleaned_data.
212 """
213 self._errors = ErrorDict()
214 if not self.is_bound: # Stop further processing.
215 return
216 self.cleaned_data = {}
217 # If the form is permitted to be empty, and none of the form data has
218 # changed from the initial data, short circuit any validation.
219 if self.empty_permitted and not self.has_changed():
220 return

Как написано в комментариях в коде - если форме разрешено быть пустой, прекращаем всякую валидацию. Значит, наша задача, привести свойство empty_permitted или метод has_changed() для каждой формы в каждом формсете к единому синхронному виду.

Переопределяем функцию has_changed(), в обоих классах, в котором мы описываем формы, использующиеся в формсетах:

def has_changed(self):
"""
Returns True if data differs from initial.
"""
if hasattr(self, 'is_change'):#проверяем, если наш динамический атрибут is_change
return True
else:
return bool(self.changed_data)


Дальше ясно - создаем динамический новый атрибут для объекта формы в случае, если в формсетах две синхронные формы имеют разные зачения has_changed(), в итоге, они станут иметь одинаковые. Ес-но, это надо проделать до валидации формсетов.

23 февраля 2009 г.

googlefight.com

Набрел на забавный сервис http://www.googlefight.com/, подсчитывает количество страниц результатов по данному запросу в гугле и выявляет победителя, например:
http://www.googlefight.com/index.php?lang=en_GB&word1=linux&word2=windows
http://www.googlefight.com/index.php?lang=en_GB&word1=linux&word2=freebsd
http://www.googlefight.com/index.php?lang=en_GB&word1=jazz&word2=pop

22 февраля 2009 г.

bash во freebsd 6.2

При установке серверов в freebsd скрипты запуска обычно копируются в /usr/local/etc/rc.d/ . Установив по необходимости систему именно freebsd и парочку серверов был озадачен тем, что скрипты-то не запускаются. То есть, ни ошибок, не предупреждений - ничего. Очень давнишний опыт настройки сервера помог мне вспомнить, что в freebsd по умолчанию стоит не bash, а как выяснилось csh.

Посему, устанавливаем bash из портов, меняем редактор по умолчанию с vi на ee (лично мне он удобнее):


# cd ~
# ee .cshrc

Изменяем setenv EDITOR ee

Перелогинились.

# cd ~
# ee .profile

Добавляем
export EDITOR=ee


# chpass

Меняем shell на /usr/local/bin/bash.

Перезагружаемся.

Кстати, я так и не понял, на чем скрипты. Но на bash у они таки заработали.

14 февраля 2009 г.

Запуск (установка и быстрая настройка) сервера subversion в debian lenny

Устанавливаем сервер и создаем репозиторий:

# apt-get install subversion
# svnadmin create /path/to/svnrepo/
# groupadd subversion
# chown -R root:subversion /path/to/svnrepo/
# chmod -R ug+rw /path/to/svnrepo/

Создаем файл:

/etc/init.d# cat svnserver
svnserve -d -r /path/to/svnrepo/
/etc/init.d# chmod 755 svnserver

Регистрируем в init.d для автозагрузки:

# update-rc.d svnserver defaults

Можно пользоваться:

# svn co svn://localhost/path/to/svnrepo/


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

/path/to/svnrepos

в поддиректориях которого могут располагаться несколько репозиториев:

/path/to/svnrepos/repo1
/path/to/svnrepos/repo2
..
/path/to/svnrepos/repoN

12 февраля 2009 г.

Моя установка (перемещение с windows) trac на debian lenny с базой postgresql

Устанавливаем базу postgresql и дополнительные нужные пакеты:

# apt-get install postgresql postgresql-client postgresql-contrib-8.3

Считаем, что python уже стоит:

# apt-get install python-psycopg2
# apt-get install postgresql-plpython-8.3
# apt-get install python-svn python-subversion

Первый пакет предоставляет доступ к базе из python.
Второй пакет устанавливает возможность писать хранимые процедуры в БД на языке python, которые используются в trac.
Третий позволяет работать с svn репозиториями из python.

Создаем базу данных для trac и пользователя (роль) для базы данных:

# su postgres
$ createuser tracuser -P
Enter password for new role:
Введите снова:
Shall the new role be a superuser? (y/n) y

Тут дописываем: /etc/postgresql/8.3/main/pg_hba.conf .

local trac tracuser md5

Это надо для того, чтобы мы могли соединяться к базе через локальный сокет с помощью нашей роли в базе, а не через tcp/ip . По умолчанию все соединения через local идут для роли безопасности в конфигурационном файле indent sameuser - вкратце, необходимо наличия такого же системного пользователя.

После изменения - "$/etc/init.d/postgresql-8.3 restart" .

Создаем базу данных:

$ createdb -T template0 -h localhost -U tracuser -W trac

Устанавливаем trac и создаем проект:

# wget ftp://ftp.edgewall.com/pub/trac/Trac-0.11.2.1.tar.gz
# tar zxfv Trac-0.11.2.1.tar.gz
# cd Trac-0.11.2.1
# python ./setup.py install
# trac-admin /path/to/myproject initenv

Это для создания нового проекта, для перемещения старого (в моем случае) копируем папку окружения, изменяем конфиг. Делаем бекап базы данных.

Например с windows:

c:\Program Files\PostgreSQL\8.3\bin>pg_dump -U admin trac > tracplain.dump

Восстанавливаем на lenny созданную базу (createlang plpythonu pg_dump сам предусмотрительно прописывает, для этого мы сделали пользователя суперюзером):

# psql -U tracuser -W -f trac.plain trac

Устанавливаем trac через mod_wsgi

# apt-get install libapache2-mod-wsgi

Прописываем в конфиге apache2

WSGIScriptAlias /trac /path/to/trac/mysite.wsgi

WSGIApplicationGroup %{GLOBAL}
AuthType Basic
AuthName "Trac"
AuthUserFile /homr/svn/passwd
Require valid-user
Order deny,allow
Allow from all


Файл с пользователями создаем с помощью passwd.

Содержание файла /path/to/trac/mysite.wsgi:

# cat mysite.wsgi
import os

os.environ['TRAC_ENV'] = '/path/to/trac/'
os.environ['PYTHON_EGG_CACHE'] = '/path/to/trac/eggs'

import trac.web.main
application = trac.web.main.dispatch_request

import site
site.addsitedir('/usr/lib/python2.5/site-packages')

Ресинхронизируем окружение:

# trac-admin /path/to/trac/ resync

Осталось настроить права для каталога окружения проекта и все должно работать.
Также можно урезать права пользователю tracuser с помощью ALTER ROLE

И напоследок, Postgresql quickstart:

1. To start postgres
# /etc/init.d/postgresql start
2. To stop postgres
# /etc/init.d/postgresql stop
3. To start using postgres, change to user postgres
$ su - postgres
4. To create new database
$ createdb dbname
5. To delete database
$ dropdb dbname
6. To access database
$ psql dbname
7. To dump database (backup)
$ pg_dump dbname > backup.out
8. Reload db from file
$ psql -d dbname -f db.out
9. To dump all database to file
$ pg_dumpall > dumpall.sql
10. Reload all from file
$ psql -f dumpall.sql
11. List database
$ psql -l
12. Clean all database
$ vacuumdb --quiet --all

Commands inside psql (PostgreSQL interactive terminal)

1. Access psql
# psql
2. Get help about commands
# \h
3. Quit psql
# \q
4. Import from file
# \i input.sql
5. Show databases
# \l
6. Show tables
# \dt
7. Show users
# \du
8. Connect to database
# \c dbname
9. Change user password
# \c template1
# ALTER USER postgres with password 'new_password';
10. Clean database
# VACUUM FULL;
11. Help on syntax command
# \h SYNTAXNAME