суббота, 6 сентября 2014 г.

Loading fixtures with initial data using new Django's core migrations

Loading fixture into db using new django core migrations

I like new django's migrations mechanism. But there is some steps we need to do to meet new standarts.

initial_data was marked as deprecated. But I want to load some data migration with user groups automatically. There is a way that helps me to do that. At first you should have, at least, initial migration. To load data into database you can follow this prompts

  1. Be sure your database is up to date with your code.
  2. Make empty migration
    python manage.py makemigrations --empty my_app
  3. Load new migration file and make it like this:
    from __future__ import unicode_literals
    from django.core.management import call_command
    from django.db import models, migrations
    from my_app import settings
    
    
    class Migration(migrations.Migration):
    
        def load_migration(apps, schema_editor):
            path_to_fixture = os.path.join(
                settings.BASE_DIR, 'formbuilder_core/fixtures/groups.json')
            call_command('loaddata', path_to_fixture)
                         
    
        dependencies = [
            ('formbuilder_core', '0001_initial'),
        ]
    
        operations = [
            migrations.RunPython(load_migration)
  4. Apply migration
    python manage.py migrate
  5. Run tests and be sure all good.

четверг, 24 апреля 2014 г.

Ansible для нужд разработки.


Хочу рассказать про софт, предназначенный для автоматизации рутинных административных задач. Такой софт может быть полезен:
  • чтобы быстро настроить чистую (или любую вообще) систему под определённые нужды;
  • чтобы быстро раскидать изменения конфигов и чего угодно по всем имеющимся системам;
  • чтобы сделать ещё что-то, что нужно делать более одного раза или более, чем на одной системе.
Из популярных реализаций - chef, puppet и ansible.

Я выбрал ansible, потому что он прост, мощен, написан на python и свободен. Конфиги пишутся на yaml, можно использовать jinja для шаблонов файлов.

По нему есть достаточно документации, а суть такова: описываем хосты в файле inventory (может быть несколько таких файлов), а потом описываем в файлах playbook, что мы хотим с этими хостами делать.

Для работы на удалённой системе там нужен только открытый ssh на любом порту, так что работает даже на простых роутерах на openwrt etc. Для комфорта понадобится python на удалённой системе (таки да, его можно установить самим ansible-ом).

Из плюшек: переменные, счётчики (итераторы, можно автоматом настроить 100 серверов, прописав каждому индивидуальное название и конфиги), шаблоны на jinja, в которые вставляются переменные, возможность слать туда-сюда файлы, править, заменять подстроки, ставить/обновлять софт, работать со службами.

Разработчики рекомендуют древовидную структуру конфигов, но если у вас всё просто, можно обойтись одной папкой (у меня задачи достаточно быстро выросли и я сделал, как советуют). Здесь hosts - файл инвентаря, *.yml - плейбуки, ansible.cfg - конфиг ансибла.

/home/nedr/progs/ansible/
├── ansible.cfg
├── dev.yml
├── first_run.yml
├── hosts
├── main.yml
├── openvz_host.yml
├── preconf.yml
├── push_hosts.yml
├── roles
│   ├── dev
│   │   ├── files
│   │   │   └── jdk-7u55-linux-x64.rpm
│   │   └── tasks
│   │       └── main.yml
│   ├── EL
│   │   └── tasks
│   │       └── main.yml
│   ├── eye
│   │   └── tasks
│   │       └── main.yml
│   ├── first_run
│   │   ├── files
│   │   │   ├── sshd_config
│   │   │   └── sshd_config_rhel
│   │   └── tasks
│   │       └── main.yml
│   ├── openvz_host
│   │   ├── files
│   │   │   └── sysctl
│   │   │       ├── 00.sysctl.conf_default
│   │   │       └── 01.sysctl.conf_with_forwarding
│   │   └── tasks
│   │       └── main.yml
│   ├── preconf
│   │   ├── files
│   │   │   ├── bash_profile
│   │   │   │   └── bash_config
│   │   │   └── sys_hosts
│   │   └── tasks
│   │       └── main.yml
│   ├── ripple
│   │   └── tasks
│   │       └── main.yml
│   └── vbox_host
│       └── tasks
│           └── main.yml
├── set_en_lang.yml
└── todo
Хосты можно группировать как угодно, древовидно. Например, сделать отдельно группу для систем под debian и под rhel, в группе rhel сделать подгруппы для деплоя и для разработки. А домашний роутер не помещать ни в какую группу. В этом случае будет родительские две группы debian и rhel, во второй будут дочерние группы deploy и dev, в них будут уже конкретные системы (деление можно продолжить). У меня ещё отделены хосты для виртуалок и сами виртуалки в них (под openvz)
openwrt

[fedora]
bb  ansible_connection=local
work
nb
tan
soh.vm ansible_ssh_port=44

[openvz_host]
sl-vhost ansible_ssh_user=xxx ansible_ssh_key_file=~/.ssh/id_rsa_sl
centos-vhost-soh ansible_ssh_port=43 ansible_ssh_host=85.17.209.152 ansible_ssh_user=lksdjf
aws 

[openvz_vhost]
eye ansible_ssh_port=2222
aws ansible_ssh_port=2222

[rhel:children]
openvz_host

[rpm:children]
fedora
rhel
Описываем действия в playbooks: это файл или структура каталогов, содержащая собственно рутинные действия.
Вот плейбук push_hosts, состоящий из одного файла и вложения, которым будет заменён /etc/hosts на удалённых системах. Таким образом везде всегда одни и те же имена, это полезно, когда привязаться по dns нельзя или сложно.
---
- hosts: all
  tasks:
    - file: src=sys_hosts dest=/etc/hosts
Пример плэйбука, который я запускаю на свежих системах, он только настраивает ssh: подключается по руту, создаёт пользователя и генерит ему ключ, прописывает открытые ключи, делает возможным sudo без пароля, настраивает sshd, разрешая только подключение юзером.
Это first_run.yml, см. структуру каталогов. Последним настраивал хост tan, осталось его имя в -hosts. В 10 строке запускаем role "first_run". Роли можно использовать многократно для разных плейбуков, хостов и т. д.
---
# run in with: ansible-playbook first_run.yml
# -k, --ask-pass        ask for SSH password
# -u REMOTE_USER, --user=REMOTE_USER
#                        connect as this user (default=nedr)

- hosts: tan
  sudo: yes
  roles:
    - first_run
В данном случае подключится файл first_run/tasks/main.yml, сам main.yml может использовать вложения.
- name: install python bindings for selinux
  yum: name=libselinux-python
  when: ansible_os_family == "RedHat"

- name: create user xxx
  user:
    name=xxx
    generate_ssh_key=yes
    groups=wheel
   
- name: set nopasswd for sudoers
  lineinfile: "dest=/etc/sudoers state=present regexp='^%wheel' line='%wheel ALL=(ALL) NOPASSWD: ALL'"

- name: enable sshd
  service: name=sshd enabled=yes
  register: sshd_enabled

- name: transmit key
  authorized_key: user=xxx key="{{ lookup('file', '/home/xxx/.ssh/id_rsa.pub') }}"

- name: send sshd config to rhel
  copy: src=sshd_config_rhel dest=/etc/ssh/sshd_config owner=root group=root mode=644 backup=yes
  when: ansible_distribution == ("CentOS" or "Scientific")
  register: config_changed

- name: send sshd config to fedora
  copy: src=sshd_config dest=/etc/ssh/sshd_config owner=root group=root mode=644 backup=yes
  when: ansible_distribution == "Fedora"
  register: config_changed

- name: restart sshd
  service: name=sshd state=restarted
#   when: config_changed|changed or sshd_enabled|changed
Софт ставится так, например (подключаем репо и ставим софт на федору)
- name: install additional repos for rhel x86_64
  yum: name=http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
  when: ansible_architecture == "x86_64" and ansible_distribution == ("CentOS" or "Scientific")

- name: install software
  yum: name={{ item }}
  with_items:
    - htop
    - mc
    - fuse-sshfs
Ansible содержит модули для управления виртуальным окружением virtualenv и pip. Было бы интересно узнать, как вы используете его для первоначальной настройки проекта.
Сайт c документацией http://docs.ansible.com/ Список официальных модулей (есть ещё неофициальные на гитхабе), посмотрите, там на любой вкус и задачу: http://docs.ansible.com/modules_by_category.html

среда, 23 апреля 2014 г.

OpenVZ: suspend and resume issue on CentOS 6.5 hosts

I had some problems with suspending/resuming of OpenVZ vhosts under CentOS host.
The error message was:
Error: No checkpointing support, unable to open /proc/cpt: No such file or directory
The solution is simple:
modprobe vzcpt
modprobe vzrst

четверг, 27 февраля 2014 г.

Simple way to make Django's devserver to serve port 80 without running it under root or dedicated web-server.

Способ запустить django devserver от пользователя и заставить его отвечать по порту 80.

In some cases we need to make devserver to answer on local domain address with standart http port 80. Linux don't allow to user to use ports below 1024.

The way to do that is not trivial, but simple. At first, make changes to /etc/hosts

127.0.0.1 ourdomain.com

Tha point is that we need to redirect http requests to django from classic devserver's 8000 port to standart http port # 80. Simpliest way to me is to using xinetd.
sudo yum install xinetd -y

Create rule in /etc/xinetd.d
    sudo vi /etc/xinetd.d/8000-to-80-redirect

Fill it:
 service 8000-to-80-redirect
  {
   type = UNLISTED
   disable = no
   socket_type = stream
   protocol = tcp
   user = root
   wait = no
   port = 80
   redirect = 127.0.0.1 8000
   log_type = FILE /tmp/8000-to-80-redirect.log
  }
Enable and run xinetd
sudo systemctl enable xinetd
sudo systemctl start xinetd

Check:
sudo systemctl status xinetd

Run django server (redundancy to see teh Magic):
django-admin.py runserver 127.0.0.1:8000

Type in browser
ourdomain.com

Enjoy! :)