пятница, 29 марта 2013 г.

Детализация звонков в Asterisk

Детализация звонков очень важная возможность контроля в работе предприятия, уверен сомнений по этому поводу не возникает. Посмотрев готовые решения я с удивлением обнаружил что действительно хороших решений не так уж и много. Одни разработки явно перегружены избыточными функциями, делая уклон в сторону биллинг систем. Другие решения ужасны дизайном. Многие решения уже давно заброшены разработчиками и более не поддерживаются.
Взвесив все за и против я решил написать собственную разработку по детализации звонков, которая будет обладать рядом преимуществ по сравнению с теми предложениями что существуют на данный момент.
  • Приятный и удобный дизайн
  • Отсутствие проблем при миграции на новые версии Asterisk
  • Возможность получать детализацию с нескольких серверов Asterisk
Разработка будет разделена на две публикации:
В первой публикации разъясняется настройка Asterisk для сбора информации о детализации звонков в базу данных. Во второй публикации информация о детализации из базы данных будет показана при помощи web интерфейса ACViewer.

Модель работы
Для получения общей детализации сразу с нескольких серверов Asterisk будет задействован RADIUS сервер. Введение дополнительного звена такого как RADIUS сервер даёт также следующие преимущества:
  • Атрибуты RADIUS со временем не изменяются, что может гарантировать лёгкость миграции на новые версии Asterisk
  • Работа по UDP протоколу снижает нагрузку на сеть при размещении RADIUS сервера и Asterisk на разном оборудовании
Работа будет вестись на дистрибутиве CentOS 6.x, в случае использования иного дистрибутива, ознакомьтесь с соответствующим разделом документации по установке программного обеспечения.

Конфигурация ПО
Конфигурация сервера MySQL
Работу начинаем с установки и настройки сервера MySQL, далее подключаемся к консоли MySQL как пользователь root и создаём базу данных в которой будут храниться данные по детализации звонков с Asterisk.

$ mysql -u root -p
CREATE DATABASE radius;
GRANT ALL ON radius.* TO 'astradius'@'127.0.0.1' IDENTIFIED BY 'radpass';
GRANT ALL ON radius.* TO 'astradius'@'localhost' IDENTIFIED BY 'radpass';
FLUSH PRIVILEGES;
SQL схему показанную ниже сохраняем в файл "radius.sql" и импортируем в базу данных.
CREATE TABLE `radacct` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `clid` VARCHAR(80) NOT NULL DEFAULT '',
    `src` VARCHAR(80) NOT NULL DEFAULT '',
    `dst` VARCHAR(80) NOT NULL DEFAULT '',
    `dcontext` VARCHAR(80) NOT NULL DEFAULT '',
    `lastapp` VARCHAR(200) NOT NULL DEFAULT '',
    `lastdata` VARCHAR(200) NOT NULL DEFAULT '',
    `duration` FLOAT UNSIGNED NULL DEFAULT NULL,
    `billsec` FLOAT UNSIGNED NULL DEFAULT NULL,
    `disposition` ENUM('ANSWERED','BUSY','FAILED','NO ANSWER','CONGESTION') NULL DEFAULT NULL,
    `channel` VARCHAR(50) NULL DEFAULT NULL,
    `dstchannel` VARCHAR(50) NULL DEFAULT NULL,
    `amaflags` VARCHAR(50) NULL DEFAULT NULL,
    `accountcode` VARCHAR(20) NULL DEFAULT NULL,
    `uniqueid` VARCHAR(32) NOT NULL DEFAULT '',
    `userfield` FLOAT UNSIGNED NULL DEFAULT NULL,
    `start` DATETIME NOT NULL,
    `answer` DATETIME NOT NULL,
    `end` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `clid` (`clid`),
    INDEX `src` (`src`),
    INDEX `dst` (`dst`),
    INDEX `start` (`start`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
$ mysql -u astradius -p radius < radius.sql

Конфигурация RADIUS
В работе будет использован сервер freeRADIUS, установим требуемые пакеты.
$ sudo yum install freeradius freeradius-mysql freeradius-utils radiusclient-ng
Конфигурация RADIUS делится на две части:
  • Конфигурация RADIUS клиента
  • Конфигурация RADIUS сервера

Конфигурация клиента radiusclient-ng
Клиент radiusclient-ng является связующим звеном между Asterisk (который является NAS в терминологии RADIUS) и сервером freeRADIUS. Следует отметить что изначально с сервером freeRADIUS поставлялся Radiusclient, но потом он оказался заброшен, новая функциональность перестала добавляться. Поэтому был сделан форк родного RADIUS клиента radiusclient-ng в который были добавлены новые возможности, его и будем использовать в работе.
Клиенту radiusclient-ng для работы с Asterisk требуется подключить файл словаря от компании Digium, находящийся в директории “contrib” архива исходных текстов Asterisk. Копируем файл словаря “asterisk.digium” и файл базового словаря который поставляется с “radiusclient-ng” в директорию с конфигурационными файлами “radiusclient-ng”
$ sudo cp /usr/share/radiusclient-ng/dictionary /etc/radiusclient-ng/
Подключаем в окончании файла “dictionary” словарь от компании Digium
$INCLUDE /usr/share/freeradius/dictionary.digium
В файле “servers” указываем учётные данные которые будут использоваться клиентом при обращении к серверу freeRADIUS. Файл “servers”:
127.0.0.1       myradiussecret
Файл “radiusclient.conf” приводим к следующему виду:
auth_order      radius
login_tries     4
login_timeout   60
nologin         /etc/nologin
issue           /etc/radiusclient-ng/issue
authserver      127.0.0.1:1812
acctserver      127.0.0.1:1813
servers         /etc/radiusclient-ng/servers
dictionary      /etc/radiusclient-ng/dictionary
login_radius    /usr/sbin/login.radius
seqfile         /var/run/radius.seq
mapfile         /etc/radiusclient-ng/port-id-map
default_realm
radius_timeout  10
radius_retries  3
login_local     /bin/login

Конфигурация сервера freeRADIUS
Файлы конфигурации сервера находятся в директории “/etc/raddb”, требуется отредактировать конфигурационные файлы находящиеся в указанной директории. Файл “clients.conf” содержит описание клиентов RADIUS которым позволено подключаться к серверу freeRADIUS. Для каждой клиентской записи требуется указать IP адрес с которого будет производиться подключение и пароль. Пароль должен соответствовать тому что указан в файле “servers” клиента “radiusclient-ng”
Файл “clients.conf”
client localhost {
        ipaddr = 127.0.0.1
        secret = myradiussecret
}
Файл “radiusd.conf” приводим к виду:
prefix = /usr
exec_prefix = /usr
sysconfdir = /etc
localstatedir = /var
sbindir = /usr/sbin
logdir = ${localstatedir}/log/radius
raddbdir = ${sysconfdir}/raddb
radacctdir = ${logdir}/radacct

name = radiusd

confdir = ${raddbdir}
run_dir = ${localstatedir}/run/${name}
db_dir = ${raddbdir}
libdir = /usr/lib64/freeradius
pidfile = ${run_dir}/${name}.pid

user = radiusd
group = radiusd

max_request_time = 30
cleanup_delay = 5
max_requests = 1024

listen {
        ipaddr = *
        port = 1812
        type = auth
}

listen {
        ipaddr = *
        port = 1813
        type = acct
}

hostname_lookups = no
allow_core_dumps = no

regular_expressions     = yes
extended_expressions    = yes

log {
        destination = files
        file = ${logdir}/radius.log
        stripped_names = no
        auth = no
        auth_badpass = no
        auth_goodpass = no
}

checkrad = ${sbindir}/checkrad

security {
        max_attributes = 200
        reject_delay = 1
        status_server = yes
}

proxy_requests  = no

$INCLUDE clients.conf

thread pool {
        start_servers = 5
        max_servers = 32
        min_spare_servers = 3
        max_spare_servers = 10
        max_requests_per_server = 0
}

modules {
        $INCLUDE ${confdir}/modules/
        $INCLUDE sql.conf
}

instantiate {
        exec
        expr
        expiration
        logintime
}

$INCLUDE policy.conf
$INCLUDE sites-enabled/
В штатной поставке freeRADIUS начиная с версии 1.1.2 уже идёт словарь от компании Digium, поэтому подключать дополнительный словарь к серверу RADIUS не требуется.
Файл “sql.conf” приводим к виду:
sql {
        database = "mysql"
        driver = "rlm_sql_${database}"
        server = "127.0.0.1"
        port = 3306
        login = "astradius"
        password = "radpass"
        radius_db = "radius"

        acct_table1 = "radacct"
        acct_table2 = "radacct"

        deletestalesessions = yes

        sqltrace = no
        sqltracefile = ${logdir}/sqltrace.sql

        num_sql_socks = 5
        connect_failure_retry_delay = 60
        lifetime = 0
        max_queries = 0
        nas_table = "nas"

        $INCLUDE sql/${database}/radcdr.conf
}
Файл "sites-enabled/default" приводим к виду:
authorize {
        preprocess
        sql
        expiration
        logintime
}

authenticate {

}

preacct {
        acct_unique
}

accounting {
        sql
        attr_filter.accounting_response
}

session {
        sql
}

post-auth {
        sql
        Post-Auth-Type REJECT {
                sql
                attr_filter.access_reject
        }
}
Символьную ссылку на файл “sites-enabled/inner-tunel” удаляем.
Создаём файл "sql/mysql/radcdr.conf" в котором описываем запрос к базе данных MySQL. При помощи указанного запроса данные детализации звонков полученные сервером freeRADIUS помещаются в MySQL таблицу.
accounting_stop_query = " \
    INSERT INTO ${acct_table2} \
        (accountcode, src, dst, dcontext, \
            clid, channel, dstchannel, lastapp, \
            lastdata, start, answer, end, duration, billsec, \
            disposition, amaflags, uniqueid, userfield) \
    VALUES \
        ('%{Asterisk-Acc-Code}', '%{Asterisk-Src}', '%{Asterisk-Dst}', '%{Asterisk-Dst-Ctx}', \
            '%{Asterisk-Clid}', '%{Asterisk-Chan}', '%{Asterisk-Dst-Chan}', '%{Asterisk-Last-App}', \
            '%{Asterisk-Last-Data}', '%{Asterisk-Start-Time}', '%{Asterisk-Answer-Time}', \
            '%{Asterisk-End-Time}', '%{Asterisk-Duration}', '%{Asterisk-Bill-Sec}', \
            '%{Asterisk-Disposition}', '%{Asterisk-AMA-Flags}', '%{Asterisk-Unique-ID}', \
            '%{Asterisk-User-Field}')"
Активируем запусе freeRADIUS сервера при загрузке системы.
$ sudo chkconfig radiusd on

Конфигурация Asterisk
Реализованная на данный момент модель работы Asterisk по протоколу RADIUS не предполагает аутентификации (Authentication) и авторизации (Authorization), пока возможен только сбор учётных данных об используемых ресурсах (Accounting). Для биллинг систем подобная модель работы конечно не годится, но для сбора детализации вполне подходит. Предполагается что сервер Asterisk уже установлен, поэтому потребуется установить лишь один пакет для работы Asterisk совместно с RADIUS сервером.
$ sudo yum install asterisk-radius
Для детализации звонков в Asterisk на имеется два модуля: RADIUS CDR Backend и RADIUS CEL Backend. Выбор пал на “CDR Backend”, поскольку модуль “CEL Backend” имеет незакрытый баг.
Всё что требуется сделать в Asterisk это привести файл конфигурации "cdr.conf" к следующему виду:
[general]

enable=yes
unanswered = yes

[radius]
usegmtime = yes    ; log date/time in GMT
loguniqueid = yes  ; log uniqueid
loguserfield = yes ; log user field
radiuscfg => /etc/radiusclient-ng/radiusclient.conf
После редактирования конфигурации подключимся к консоли Asterisk и перезагрузим модуль.
localhost*CLI> module unload cdr_radius.so
localhost*CLI> module load cdr_radius.so
Loaded cdr_radius.so
 == Parsing '/etc/asterisk/cdr.conf':   == Found
Loaded cdr_radius.so => (RADIUS CDR Backend)
Готово! Делаем звонок.
Подключаемся к MySQL серверу, и убеждаемся в корректной работе детализации.
mysql> use radius;
Database changed
mysql> SELECT src, dst, start, end, duration, answer  FROM radacct;
+-----+-----+---------------------+---------------------+----------+---------------------+
| src | dst | start               | end                 | duration | answer              |
+-----+-----+---------------------+---------------------+----------+---------------------+
| 100 | 500 | 2013-03-29 15:57:15 | 2013-03-29 15:57:22 |        7 | 2013-03-29 15:57:15 |
| 100 | 500 | 2013-03-29 16:13:31 | 2013-03-29 16:13:35 |        4 | 2013-03-29 16:13:31 |
+-----+-----+---------------------+---------------------+----------+---------------------+
2 rows in set (0.00 sec)
Получить детализацию с дополнительного сервера Asterisk достаточно просто, требуется лишь добавить секцию клиента в файле “clients.conf” и дать возможность серверу RADIUS слушать соединения на нужных сетевых интерфейсах. После этого можно переходить к настройке дополнительного сервера Asterisk с клиентом radiusclient-ng.

Отображение информации о детализации из базы данных при помощи WEB интерфейса описано в следующей публикации.

суббота, 23 марта 2013 г.

Типовая конфигурация сервера MySQL

Многие администраторы в своей работе используют шаблоны готовых конфигураций. Подобный подход вполне разумен, в этом случае сокращается время на развёртывание сервиса, уменьшается вероятность ошибок, не требуется постоянно помнить опции конфигурации. Всем кому интересен подобный подход предлагаю воспользоваться моими наработками оформленными в файле конфигурации MySQL.

В основе конфигурации лежит шаблон my-large.cnf и наработки взятые из блога Sergey Danielyan. Конфигурация для сервера MySQL  5.1 обладает следующими возможностями:
  • Транзакционным механизмом InnoDB
  • Кодировкой UTF-8
  • Ограничением на бинарные лог файлы по времени (2 суток) и по максимальному размеру (1Гб)
  • Ожиданием подключений только на адресе 127.0.0.1
В дистрибутиве CentOS 6.x сервер MySQL устанавливаем при помощи команды
$ sudo yum groupinstall "Сервер базы данных MySQL"
Листинг файла конфигурации /etc/my.cnf
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
default-character-set = utf8

[mysqld]
port = 3306
bind-address = 127.0.0.1
socket = /var/lib/mysql/mysql.sock
init_connect='SET collation_connection = utf8_unicode_ci'
character-set-server = utf8
collation-server = utf8_unicode_ci

skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 8

log-bin = mysql-bin
expire_logs_days = 2
max_binlog_size = 1024M
binlog_format = mixed
log-error = /var/log/mysqld.log

server-id = 1

default-storage-engine = InnoDB
innodb_data_home_dir = /var/lib/mysql
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /var/lib/mysql
innodb_buffer_pool_size = 256M
innodb_additional_mem_pool_size = 20M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 128M
sort_buffer_size = 128M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout
Запускаем установленный MySQL сервер
$ sudo service mysqld start
Завершаем конфигурирование
$ sudo /usr/bin/mysql_secure_installation
При новой установке MySQL пароль на root пользователя отсутствует, поэтому просто нажимаем Enter и далее в конфигурации устанавливаем новый пароль. В большинстве вопросов которые будут задаваться в конфигурационном меню подходят ответы заданные по умолчанию.

Последним штрихом активируем запуск MySQL сервера при загрузке системы
$ sudo chkconfig mysqld on

пятница, 18 января 2013 г.

Решение проблемы "unable to connect to remote asterisk"

Довольно часто, да что там, практически постоянно мы видим данную надпись после свежей установки Asterisk на сервер. Происходит подобная ошибка потому что Asterisk запускается сразу, без предварительной настройки сервиса. Как результат, попытка подключиться к Asterisk при помощи команды "asterisk -r" огорчает нас следующим сообщением:
Unable to connect to remote asterisk (does /var/run/asterisk/asterisk.ctl exist?)
Я опишу последовательность шагов которые позволят избежать появление данной ошибки. Asterisk запускаем на дистрибутивах CentOS 5 или CentOS 6, в других дистрибутивах содержание и местонахождение файлов может отличаться.
  1. Создаём пользователя. На сервере нам потребуется пользователь под которым будет запускаться Asterisk, заводим пользователя с командой “useradd asterisk”. Параметры по умолчанию заданные при создании пользователя можно посмотреть с помощью команды “useradd -D”. При создании пользователя будет также создана одноимённая группа.
  2. Настраиваем запуск Asterisk. Открываем на редактирование файл "/etc/sysconfig/asterisk" и выставляем переменные "AST_USER" и "AST_GROUP" в соответствии с созданным пользователем под которым должен быть запущен Asterisk. Если имя пользователя совпадает с именем группы то оставляем "AST_GROUP" закомментированным, в этой переменной будет использовано значение из "AST_USER". При отсутствии файла "/etc/sysconfig/asterisk" переменные "AST_USER" и "AST_GROUP" могут также выставляться в файле "/etc/rc.d/init.d/asterisk".
  3. Выставляем права на файл asterisk.ctl. Открываем на редактирование файл “/etc/asterisk/asterisk.conf” и в разделе [files] выставляем следующую конфигурацию:
[files]
astctlpermissions = 0660
astctlowner = asterisk
astctlgroup = asterisk
astctl = asterisk.ctl
Перезапускаем Asterisk и подключаемся с помощью команды
$ asterisk -r

четверг, 27 декабря 2012 г.

Использование EFI BIOS для загрузки CentOS

Улучшения неизбежны
Время летит быстро и вот уже на повсюду на прилавках магазинов маячат 2ТБ накопители. И всё бы шло своим чередом в плане увеличения ёмкости, ставь более вместительный HDD да ставь, вот только при установке накопителя в 2.5ТБ пользователь уже сталкивается с проблемой - ограничение 2,2ТБ на раздел. В этом случае надо уже использовать GPT таблицу разделов. И тут мы, пользователи линуксов подходим к другому ограничению - загрузчик grub не понимает таблицу разделов GPT. grub2 понимает, а вот grub в своё время этому не научили. Казалось бы, современные дистрибутивы уже вполне таки обзаводятся grub2. Новые дистрибутивы да, обзаводятся. Но не надо забывать и о серверных дистрибутивах, в которых основная задача как раз поддержка системы с учётом неизменности мажорных версий ПО. Что же делать в этом случае? Нам поможет загрузка с помощью EFI BIOS!

Я давно уже хотел выяснить что же из себя представляет технология загрузки операционной системы из EFI BIOS. Технология разрабатывается давно, но понятной информации, представленной в виде последовательности шагов по переходу с обычной загрузки операционной системы при использовании “MBR” записи на накопителе на загрузку с использованием EFI BIOS я почему то не нашёл. Эта статья и призвана заполнить образовавшийся пробел.

Итак, нам требуется материнская плата с EFI BIOS, в целом скорее всего это будет любая материнская плата способная работать с Sandy Bridge архитектурой процессоров. Наверняка материнские платы с EFI BIOS есть и от компании AMD, мне они не знакомы. В любом случае есть ли поддержка подобного BIOS или такая поддержка отсутствует можно выяснить на сайте производителя конкретной материнской платы. Я приобрёл материнскую плату от ASUS P8Q77-M. Дальнейшая работа будет вестись с этой платой.

Новый накопитель, на который требуется перенести систему. Для себя я выбрал Seagate ST2000DM001. На него и будем переносить систему. Многие возразят, ведь данный накопитель ниже обозначенного предела в 2.2ТБ и в этом случае можно обойтись без загрузки с помощью EFI BIOS, разместив загрузчик в MBR. Что тут скажешь - это конечно же так. Вот только следующий порог ёмкости накопителя находится уже в районе 2.5ТБ и уж с ним точно возникнут сложности. Я решил не откладывать решение этого вопроса на потом, когда у меня появится накопитель бОльшей ёмкости, а попробовать разобраться во всём сейчас.

И наконец установленная в данный момент система CentOS 6.3, которую и надо перенести на новый накопитель.

UEFI
Для лучшего понимания дальнейших действий требуется прояснить каким образом осуществляется загрузка с помощью EFI BIOS.
  1. Система включается, запускаются POST тесты
  2. Загружается EFI BIOS
  3. В EFI BIOS находится собственный менеджер загрузки, с помощью которого выясняется какие EFI приложения должны запуститься и откуда (например указан диск, раздел) 
  4. Менеджер загрузки запускает EFI приложения с раздела отформатированного под файловую систему FAT (HFS/HFS+ для Apple-Intel Mac). Этот раздел зовётся EFI System Partition (ESP)
  5. EFI приложения могут запускать другие приложения
Исходя из этой информации можно понять что для загрузки операционной системы нам требуется указать менеджеру загрузки который находится в EFI BIOS требуемый диск на котором находится наше EFI приложение.
  • Переменные с информацией о путях загрузки EFI приложений можно указать с помощью так называемого UEFI Shell. Скачиваем его по ссылкам, вскоре он нам понадобится. Указанная оболочка достаточно мощное средство работы с EFI BIOS, нам же требуется только указание пути к EFI приложению.
    x86_64 UEFI Shell 2.0 (Beta)
    i386 UEFI Shell 2.0 (Beta)
  • EFI приложение поставляется вместе с CentOS 6 (RHEL 6) и находится в директории “/boot/efi/EFI/redhat/”. В этой директории находится только один файл - grub.efi
    Если диск который будет установлен размечается на разделы в отдельной операционной системе, эти файлы лучше сразу скопировать куда нибудь на переносной носитель. Если же новый диск подключен к системе которая будет переноситься, просто запоминаем местонахождение скачанного файла EFI Shell и EFI файла приложения от Red Hat.

Разметка нового диска
Размечать новый диск будем программой parted, поскольку fdisk и не может работать с GPT таблицами разделов. Перед разметкой желательно уточнить тип физического сектора который имеет диск - 512Б или 4КБ. Это можно выяснить запустив программу parted с указанием нового диска. Как можно видеть из вывода parted, модель диска которую я приобрёл имеет 4КБ сектор взамен стандартного 512Б. А это значит что для избежания просадки в скорости работы требуется ровнять создаваемые разделы по границе в 1МБ.



Для разметки в этом случае к программе parted применяется ключ “-a optimal” и первый раздел начинается не с нуля, а с 1МБ. Обратитесь к статье Выравнивание раздела диска в случае необходимости.
Итак, запускаем parted с указанием нового диска который требует разметки
parted -a optimal /dev/new_disk
Приступаем к созданию новых разделов
(parted) mklabel gpt
(parted) unit MB
(parted) mkpartfs "EFI System Partition" fat16 1 20
(parted) mkpartfs primary ext2 20 200
(parted) mkpart primary 201 -1
(parted) set 1 boot on
(parted) set 3 lvm on
(parted) p
  • Первый раздел у нас будет так называемый EFI System Partition (ESP). Файловая система на нём должна быть обязательно FAT, разрядность не важна. Можно создать FAT12, FAT16 или FAT32. В последнем случае минимальный раздел у этого типа - 512МБ, что явно избыточно для маленького системного раздела который требуется. FAT16 с минимумом в 20МБ будет вполне достаточно. Именно на этот раздел будут помещены EFI файл оболочки и EFI файл представленный компанией Red Hat. 
  • Второй раздел требуется для директории /boot. В этой директории находится grub, файлы ядер (kernel) и образов (initrd). Из файловых систем для этой цели лучше всего подходит ext2. Поскольку у grub отсутствует возможность загружаться из LVM раздела нам требуется выделить под него отдельный раздел. Если LVM не планируется, достаточно будет сделать второй раздел корневым и отвести ему всю оставшуюся ёмкость накопителя. В случае использования менеджера логических томов LVM, переходим к созданию заключительного раздела на накопителе.
  • Третий раздел отводится под LVM. Под этот раздел отводится вся оставшаяся ёмкость диска.
  • Устанавливаем дополнительные флаги разделов: boot и lvm 
При просмотре таблицы разделов командой должна появиться приблизительно следующая информация.


Перенос системы на новый накопитель
Монтируем созданный системный раздел в подходящую директорию
$ sudo mount -t vfat /dev/sda1 /mnt
На этот раздел требуется скопировать файл оболочки и EFI файл приложения от Red Hat. Скачанный файл оболочки размещаем под именем Shellx64.efi прямо в корень раздела, а файл приложения который находится в директории “/boot/efi/EFI/redhat/” переносим в созданную директорию “/EFI/redhat/”. В эту же директорию требуется скопировать файл конфигурации grub.conf, который находится в директории “/boot/grub/grub.conf”. Следует учесть, что поскольку нумерация разделов изменилась, требуется отредактировать файл grub.conf на актуальную конфигурацию, замените в этом файле строки с (hd0,0) на (hd0,1).
На этом работу с системным разделом EFI можно считать завершённой. Отключаем системный раздел командой umount и монтируем раздел который у нас будет как /boot.
$ sudo mount /dev/sda2 /mnt
На вновь подключенный раздел копируем всё что находится у нас в директории /boot с диска на котором в данный момент находится система. Если раздел /boot находится у вас на корневом разделе, то копируем и остальные файлы системы. В случае если у вас корневой раздел, /swap, /home и прочие разделы находятся на LVM, переносим LVM на новый диск. Подробнее о том как это сделать можно прочитать в Повести о Linux и LVM Помним о том что требуется изменить файл /etc/fstab, указав в нём местонахождение разделов нового накопителя. При использовании LVM в файле /etc/fstab возможно потребуется изменить только местонахождение корневого раздела.

Запуск EFI Shell
Перезагружаем систему и заходим в EFI BIOS. Нам требуется отыскать надпись "Launch EFI Shell from file system device". Эта надпись может находиться в разделе “Boot Option Menu”, либо при явном выборе меню “Exit”. Подтверждаем выбор и после этого менеджер загрузки начинает искать EFI приложение на подключенных накопителях (HDD, USB Flash и пр.), с последующим запуском найденного приложения.
У вас на экране монитора должно появиться запущенное приложение EFI Shell. Возможно, после подтверждения выбора надписи "Launch EFI Shell from file system device" у вас появится сообщение о том что “FileName.efi not found”, в этом случае файл Shellx64.efi следует переименовать на то имя которое запрашивается.
Итак, EFI Shell запущен, теперь можно приступать к указанию пути к EFI приложению размещённому так же на системном разделе. 

Просмотрим информацию о загрузочных записях которые существуют в данный момент
Shell> bcfg boot dump -v
Добавим четвёртую (счёт начинается с нуля) опцию к загрузочному меню. Обратите внимание на то что для указания пути используется обратный слэш.
Shell> bcfg boot add 3 fs0:\EFI\redhat\grub.efi "CentOS"
Если потребуется удалить вновь созданную четвёртую опцию, поможет команда
Shell> bcfg boot rm 3
Для изменения позиции с #4 на #0 поможет команда
Shell> bcfg boot mv 3 0
Последнее можно сделать и из меню EFI BIOS, в разделе приоритетов загрузки.
С дополнительной информацией можно ознакомиться в статье по UEFI
Как видите EFI Shell предоставляются достаточно большие возможности по работе со значениями EFI BIOS находящимися в NVRAM. Выходим из EFI Shell по команде exit, перезагружаем систему и при повторном посещении EFI BIOS мы видим что в разделе приоритетов загрузки (Boot option priorities), помимо выбора подключенных накопителей появилась возможность выбора опции "CentOS (ёмкость накопителя)". После выбора новой опции, требуется изменить дополнительно опции в разделе "CSM" (Compatibility Support Module) - "Launch CSM" - "auto" и в разделе "Secure boot" - "OS Type" - "Other OS". В BIOS разных производителей эти разделы могут именоваться несколько иначе, суть в том чтобы указать загрузку именно EFI приложения с системного раздела, а не MBR запись. В последнем случае у вас на дисплее появится сообщение о том что MBR запись не найдена (что вполне логично, потому что она действительно должна отсутствовать на новом накопителе). Перезагружаем систему и видим запуск знакомого загрузчика grub на новом накопителе! 

Финальные штрихи
В целом система готова к использованию, осталась лишь пара деталей. При обновлении ядра системы у нас обновляются также и опции загрузки нового ядра в файле “/boot/grub/grub.conf”, но теперь файл grub.conf находится в директории “/EFI/redhat/” на другом разделе накопителя. Поэтому при очередном обновлении всё равно будет загружено предыдущее ядро, поскольку записи в этом файле не будут обновлены. Чтобы это исправить, примонтируем ESP раздел к директории “/boot/efi” и создадим символьную ссылку на новый файл конфигурации в директории “/boot/grub” (неиспользуемый файл конфигурации в этой директории следует удалить). Будет разумнее сделать монтированием с использованием UUID раздела. Узнать его можно с помощью команды
blkid /dev/partition_name
Добавляем записи в файл /etc/fstab
UUID=b460fc21-d517-4592-9e3e-348b7a88c8f0 /boot     ext2    defaults           1 2
UUID=A774-EAC4                            /boot/efi vfat    rw,umask=077       0 0
Создаём символьную ссылку на файл grub.conf
ln -s /boot/efi/EFI/redhat/grub.conf /boot/grub/grub.conf
Перенос системы завершён, протестируем новый накопитель.


среда, 15 августа 2012 г.

Виртуализация с технологией VT-d в “домашних” условиях

Заняться виртуализацией двигало появившееся у меня желание сократить количество компьютеров в доме. У меня уже давно находится компьютер который является Wi-Fi точкой доступа, FTP сервером, является качалкой torrent и прочее. Вся работа на нём ведётся под управлением OC Linux. После покупки программно-аппаратного комплекса PC-3000 UDMA пришлось собрать ещё один компьютер под управлением Windows. PC-3000 оборудование хорошее, но к сожалению в сторону Linux разработчики даже не смотрят. Я решил объединить две системы в один компьютер используя виртуализацию, при этом Linux будет использоваться как основная система, а работа с PC-3000 будет вестись из гостевой виртуальной машины с Windows. Ситуация осложнялась тем что для такого объединения простая аппаратная виртуализация VT-x (Intel VT или AMD-v) имеющаяся на множестве процессоров мне не подходила. Для подобной системы требовалась более продвинутая аппаратная виртуализация, виртуализация ввода-вывода, называемая VT-d. Именно этот тип виртуализации позволяет пробросить любое устройство воткнутое в PCI или PCI-e шину в гостевую виртуальную систему.



Какие преимущества получаются при использовании такой системы? 

  • Пониженное потребление электроэнергии. Очевидно что одна система потребляем меньше электроэнергии чем две.
  • Снижение стоимости. Это преимущество актуально для тех кто только собирается собирать систему для ремонта или задумывается об обновлении платформы собранной для ремонта
  • Повышенная надёжность. Сервер как правило комплектуется источником бесперебойного питания, что позволит продолжать работу во время кратковременного пропадания электроэнергии.
  • Возможность удобно масштабировать дисковое пространство. При сохранении информации из виртуальной машины с использованием Samba или FTP сервиса, увеличение дискового пространства для виртуальной машины будет абсолютно прозрачным.
  • Удобство работы. Отсутствует привязка к рабочему месту. Подключив накопитель с которым требуется поработать можно подсоединившись удалённо к виртуальной машине продолжить работу с накопителем. При этом виртуальную машину можно перезагружать, выключать, снова включать зная что даже если возникнут серьёзные проблемы на этапе загрузки виртуальной машины их можно устранить удалённо.
  • Для меня так же очевидным преимуществом является опыт в работе с технологиями виртуализации получаемый при построении подобной системы.
Выбор оборудования
Создание платформы начнём с подбора оборудования. Для работы технологии виртуализации ввода-вывода VT-d необходима соответствующая поддержка со стороны материнской платы, BIOS (или EFI) материнской платы и реализация технологии VT-d в процессоре.

Начнём с выбора материнской платы. Технология VT-d гарантированно обслуживается линейкой чипсетов серии “Q”, начиная с самой ранней модели чипсета Q35 и заканчивая современной на данный момент моделью чипсета Q77. Это сужает круг поисков требуемой материнской платы, всё что нам нужно это посмотреть предложения материнских плат на рынке с данными типами чипсета. Мой выбор пал на модель от ASUS P8Q77-M, mATX формата. Хоть и дороговатая, но качественная, современная материнская плата. Ваш выбор возможно будет отличаться от моего, тут уж кому какой производитель но душе.

Проверяем поддержку VT-d на уровне BIOS или EFI. Тут достаточно просто, с материнскими платами идут инструкции по эксплуатации которые можно скачать с сайта производителя. Скачиваем инструкцию и начинаем искать в районе раздела “Advanced menu” строчку “Intel Virtualization Technology”. Эта строчка означает что есть поддержка технологии VT-x и помимо этого, при поддержке технологии VT-d к этой строчке обязательно должна идти строка “Intel TXT(LT) Support” заявляющая о гарантированной поддержке необходимой нам технологии Intel VT-d (Virtualization Technology for Directed I/O, технология виртуализации ввода/вывода).
Подбор процессора с поддержкой VT-d. 

Для подбора требуемого процессора воспользуемся выбором процессора по определённым критериям на сайтом компании Intel. По ссылке представлены Core i5 процессоры с поддержкой технологии VT-d с TDP от 45-и ватт (убраны варианты для мобильных систем). По возможности приобретайте процессор который идёт сразу с вентилятором, в этом случае в прайс листе продавца рядом с наименованием процессора идёт пометка “BOX”. Вентилятор в комплекте идёт достаточно тихий и качественный.

Желательно убедиться что выбранный процессор поддерживается выбранной материнской платой. Как правило таблица поддерживаемых процессоров находится на сайте производителя, посмотрите соответствие по наименованию процессора и версии BIOS материнской платы с которой эта поддержка анонсирована. При необходимости обновите BIOS до актуальной версии.

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

[midnighter@localhost ~]$ yum groupinstall "Платформа виртуализации"

Настройка платформы виртуализации
Итак, все требуемые аппаратные и программные компоненты у нас имеются, самое время приступить к настройке.
  1. Активируем подержку VT-d в BIOS
    При старте системы по нажатию клавиши “Del” на клавиатуре попадаем в BIOS. Место расположения нужных опций которые требуется активировать отличается от поставщика BIOS, как правило это раздел “Advanced menu”. В этом разделе ищем строчки “Intel Virtualization Technology” и “Intel TXT(LT) Support” которые требуется переключить в “enabled”. По умолчанию как правило все опции виртуализации заблокированы.
  2. Активируем поддержку VT-d в ядре
    Для этого нам требуется добавить параметр intel_iommu=on к строке конфигурации ядра в файле /boot/grub/menu.lst
    Кроме того возможны случаи когда система может иметь проблемы с таблицами ACPI. Это проявляется в непрерывных сообщениях в логе похожих на подобную запись.
    dmar: DMAR:[DMA Read] Request device [00:02.0] fault addr 7f800000 
    dmar: DRHD: handling fault status reg 3
    
    В случае если такая проблема возникла для её устранения достаточно добавить запись intel_iommu=igfx_off 
    Пример ниже демонстрирует модифицированную запись файла menu.lst
    default=0
    timeout=5
    splashimage=(hd0,0)/grub/splash.xpm.gz
    hiddenmenu
    title Red Hat Enterprise Linux Server (2.6.32-36.x86-645)
            root (hd0,0)
            kernel /vmlinuz-2.6.32-36.x86-64 ro root=/dev/VolGroup00/LogVol00 rhgb quiet intel_iommu=on intel_iommu=igfx_off
            initrd /initrd-2.6.32-36.x86-64.img
    
  3. Перезагрузка системы
    Для применения новой конфигурации требуется перезагрузка. После перезагрузки проверяем активацию технологии виртуализации.
    midnighter@localhost ~]$ dmesg | grep "Virtualization Technology"
    PCI-DMA: Intel(R) Virtualization Technology for Directed I/O
    
Начиная с этого момента начала работать платформа с активированной технологией VT-d.

Настройка сервиса виртуализации
Программная часть виртуализации основана на сервисе libvirtd. Требуется убедиться что сервис стартует вместе с загрузкой основной системы, нам в этом поможет команда
[midnighter@localhost ~]$ chkconfig --list | grep libvirtd
libvirtd            0:выкл  1:выкл  2:выкл  3:вкл   4:вкл   5:вкл   6:выкл
В противном случае устанавливаем загрузку на уровнях 3, 4, 5 во вкл
Далее в файле /etc/sysconfig/libvirtd убираем комментарий со строки
# Listen for TCP/IP connections
# NB. must setup TLS/SSL keys prior to using this
LIBVIRTD_ARGS="--listen"
в файле /etc/libvirtd/libvirtd.conf убираем коментарии со строк
isten_tls = 0
listen_tcp = 1
Подобная конфигурация допустима на время тестирования. Позже если открываете доступ к виртуальной машине из локальной сети или интернета, обязательно настройте безопасный доступ в этом же конфигурационном файле.

Перезагружаем сервис виртуализации для того чтобы новая конфигурация вступила в силу
[midnighter@localhost ~]$ sudo service libvirtd restart
Создаём пользователя в SASL с помощью которого будем подключаться к сервису виртуализации.
[midnighter@localhost ~]$ sudo saslpasswd2 -a libvirt -c midnighter
Образы виртуальных машин хранятся в директории “/var/lib/libvirt/images”, целесообразно будет под образы выделить отдельный LVM том и добавить его автомонтирование в файл “/etc/fstab”. После этой операции определяемся с гостевой ОС. Я рекомендую установить Windows 7 Home Basic 32-х битной архитектуры. Почему именно эта система? Более продвинутые версии имеют в своём составе сервисы которые в холостую будут потреблять процессорное время попусту грея воздух и расходуя электроэнергию, Home Basic вполне достаточно для обычной работы. Оперативной памяти под такую гостевую систему которая будет работать только с ПО PC-3000 выделять более 2гб. излишне, поэтому вполне достаточно будет 32-х битной архитектуры. Теперь мы можем работать с образом виртуальной машины имеющим некоторый набор виртуального оборудования, но запускать такой контейнер и устанавливать на него операционную систему пока ещё рано.

Подключение к виртуальной машине
Для возможности удалённого подключения к сервису виртуализации требуется убрать комментарии со строчек vnc_listen = “0.0.0.0” и spice_listen = “0.0.0.0” в файле /etc/libvirt/qemu.conf и применить данную конфигурацию командой
[midnighter@localhost ~]$ sudo service libvirtd restart
При создании образа виртуальной машины идёт комплектация определённым набором оборудования настроенного по умолчанию. Графический адаптер в списке этого оборудования настроен на соединение с адресом “127.0.0.1”, поэтому требуется создать новый графический адаптер у которого после правки файла “/etc/libvirt/qemu.conf” появилась возможность указать “прослушивать все доступные интерфейсы”. В противном случе при удалённом подключении появится сообщение "ошибка соединения просмотрщика с хостом гипервизора". Позже обязательно настройте безопасный авторизованный доступ в файле “/etc/libvirt/qemu.conf”.

Подключаться к сервису виртуализации можно с помощью менеджера виртуальных машин, с помощью этой программы можно создавать и смотреть вывод дисплея виртуальной машины по протоколу VNC или SPICE. Какой протокол будет использоваться указываем в конфигурации видеоадаптера при создании машины. Также есть возможность отдельно сконфигурировать образ виртуальной машины консольной утилитой virsh, а затем для просмотра вывода дисплея виртуальной машины использовать программу для работы с протоколом VNC.

Пробрасываем устройство
Самый простой способ пробросить устройство при создании образа виртуальной машины это воспользоваться программой “менеджер виртуальных машин”. В этом случае при создании машины в разделе “Параметры виртуального оборудования” нажимаем кнопку “Добавить оборудование”. В появившемся списке выбираем “PCI Host Device” и после выбора этого пункта у нас появляется дополнительный перечень оборудования которое мы можем пробросить. Выбираем оборудование и после перезагрузки виртуальной машины всё что требуется сделать это установить драйвера на это оборудование. У меня это PC-3000 для которого я и установил требуемые драйвера и необходимое для работы программное обеспечение.

Работа с помощью консольной утилиты более сложна и детально описана в разделе 12.1 документации по пробросу PCI устройств с помощью virsh.




Как можно видеть из этой статьи, пробросить можно любое оборудование установленное в PCI или PCI-e шину и при этом полноценно работать и ним из виртуальной гостевой операционной системы.

воскресенье, 27 мая 2012 г.

Asterisk realtime queue_log

Продолжаем рассказ о подключении к Asterisk 1.8 архитектуры реального времени или как её иначе называют realtime. О получении с использованием realtime конфигурации musiconhold рассказано в предыдущей публикации, если realtime на Asterisk настраивается впервые, рекомендуется обратиться к этой статье для первоначальной настройки. 
На этот раз мы будем подключать queue_log. Как было замечено в предыдущей публикации одним из препятствий с которым приходится сталкиваться при подключении realtime является отсутствии структуры таблицы. Те таблицы что в обилии есть на просторах интернета уже давно не актуальны, а те что идут вместе с исходным кодом Asterisk приходится модифицировать. 

При создании структуры таблицы из поставляемого с исходным кодом Asterisk файла дампа queue_log.sql в лог файле Asterisk у нас появятся ошибки:

“Realtime table queue_log@general: Column time cannot be a datetime res_config_mysql.c: Table queue_log requires a column 'data' of size '0', but no such column exists.
res_config_mysql.c: MySQL RealTime: Failed to insert into database: Unknown column 'data' in 'field list'”

Нам требуется модифицированная SQL таблица которая представлена ниже

CREATE TABLE `queue_log` (
       time varchar(32) default NULL,
       callid char(64) default NULL,
       queuename char(64) default NULL,
       agent char(64) default NULL,
       event char(32) default NULL,
       data char(64) default NULL,
       data1 char(64) default NULL,
       data2 char(64) default NULL,
       data3 char(64) default NULL,
       data4 char(64) default NULL,
       data5 char(64) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Рассмотрим по порядку назначение каждого поля.

time - Дата и время события. С некоторых пор к дате и времени через точку добавляются микросекунды, после этого поле таблицы по понятным причинам уже не может быть SQL формата datetime, меняем формат поля на varchar.
callid - "REALTIME", "NONE", или уникальный идентификатор канала.  
queuename - Имя затронутой очереди пока описанной в конфигурационном файле queues.conf
agent - Одно из значений ADDMEMBER, REMOVEMEMBER, RINGNOANSWER, EXITEMPTY, TRANSFER, AGENTDUMP, ABANDON, SYSCOMPAT, CONNECT, COMPLETECALLER, COMPLETEAGENT, AUSEALL, UNPAUSEALL, PAUSE, UNPAUSE, PENALTY, ENTERQUEUE, EXITWITHTIMEOUT, EXITEMPTY, EXITWITHKEY, или значение определённое пользователем.
data ... data5 - Аргументы связанные с событием описанном в поле event.

В конфигурационном файле логов Asterisk logger.conf по умолчанию идёт настройка таким образом, что как только для queue_log появляется возможность работы с realtime сразу начинается запись в базу данных. Поэтому теперь нам лишь требуется убрать комментарий перед надписью “queue_log => mysql,general” в конфигурационном файле extconfig.conf, выполнить команду из консоли Asterisk “module reload” и можно начинать смотреть данные которые начнут появляться в MySQL таблице queue_log. Файл queue_log находящийся в директории “/var/log/asterisk” нам больше не понадобится и его можно удалить.

суббота, 26 мая 2012 г.

Asterisk realtime

Что нам стоит “Asterisk realtime” построить!


Настройка Asterisk с использованием текстовых конфигурационных файлов приемлема на начальных этапах эксплуатации, но ещё более удобна настройка с использованием какой либо распространённой базы данных. В данной публикации будет рассмотрена работа с использованием архитектуры реального времени “Asterisk Realtime Architecture” или просто realtime.
Realtime существует в двух типах - статическом и динамическом. Статический тип похож на метод чтения из конфигурационного файла, только в данном случае все значения конфигурационного файла у нас находятся в базе данных. Чтобы заполучить изменённую конфигурацию при статическом типе realtime требуется перезагрузить модули командой “module reload” из консоли сервера Asterisk. Динамический же тип realtime, напротив, получает требуемую конфигурацию сразу по мере необходимости без какой либо перезагрузки модулей.

В интернете находится разрозненная информация о том как настроить realtime применительно к ранним версиям Asterisk. В открывающемся цикле статей я буду обобщать свой опыт настройки Asterisk realtime. Будет рассмотрено использование архитектуры реального времени на примере LTS версии Asterisk 1.8 с использованием дистрибутива CentOS 5.x при подключении к MySQL базе данных.

Настройка сервера Asterisk

Конфигурация Asterisk realtime находится в трёх файлах - extconfig.conf, res_config_mysql.conf и cdr_mysql.conf.

extconfig.conf отвечает за realtime конфигурацию iaxusers, iaxpeers, sippeers, sipregs, voicemail, extensions, meetme, queues, queue_members, musiconhold, queue_log и ряда файлов со статическим типом конфигурации. Все эти записи закрыты комментариями, мы будем убирать комментарии по ходу настройки и создания соответствующих таблиц в базе данных MySQL.
Надо заметить что изменился формат записей по отношению к предыдущим версиям Asterisk. Если в ранних версиях для настройки realtime формат записи был: “<family name> => <driver>,<database name> [,table_name]”, то теперь он стал “<family name> => <context> [,table_name]”. Как мы видим перечисления “driver” и “database name” представлены как отдельный “context”. Описание контекста находится в файле “res_config_mysql.conf”, при конфигурации по умолчанию контекстом у нас является “general”. Необязательное значение “[table_name]” не указывается в случае если “<family name>” совпадает с именем таблицы создаваемой в базе MySQL.

res_config_mysql.conf отвечает за подключение к MySQL базе данных. Разберём конфигурацию подключения. При просмотре файла мы видим следующие записи, практически все они закрыты комментариями.
[general]
;dbhost = 127.0.0.1
;dbname = asterisk
;dbuser = myuser
;dbpass = mypass
;dbport = 3306
;dbsock = /tmp/mysql.sock
;dbcharset = latin1
;requirements=warn ; or createclose or createchar
Требуется снять комментарии со всех вышеприведённых строчек, за исключением “dbsock = /tmp/mysql.sock” и изменить значения записей dbuser, dbpass и dbcharset на те значения что использовали при создании базы данных.

Предполагается что сервер MySQL у нас уже установлен, сконфигурирован под хранилище “InnoDB” и использует кодировку “utf8”. Поэтому подключившись пользователем root к серверу MySQL, создаём базу данных и пользователя.
CREATE DATABASE asteriskdb;
GRANT ALL PRIVILEGES ON asteriskdb.* TO 'asterisk'@'localhost' IDENTIFIED BY 'mypass' WITH GRANT OPTION;
flush privileges;
После подключения к консоли сервера Asterisk и применения новой конфигурации проверяем соединение с базой.
module reload
realtime mysql status
general connected to asteriskdb@127.0.0.1, port 3306 with username asterisk for 1 days, 1 hours.
cdr_mysql.conf отвечает за подключение к базе данных MySQL при использовании записи звонков (Call Detail Records). Используется для статистики звонков или основанного на CDR биллинга звонков. По умолчанию запись звонков ведётся в CSV файл “/var/log/asterisk/cdr-csv/Master.csv”. При просмотре файла мы видим записи похожие на те что были в конфигурационном файле res_config_mysql.conf.
;[global]
;hostname=database.host.name
;dbname=asteriskcdrdb
;table=cdr
;password=password
;user=asteriskcdruser
;port=3306
;sock=/tmp/mysql.sock
;timezone=UTC ; Previously called usegmtime
Теперь, так же как и ранее в файле res_config_mysql.conf нам требуется снять комментарии со всех вышеприведённых строчек, за исключением “sock = /tmp/mysql.sock” и изменить значения записей hostname, dbname, password и user на те значения что использовали при создании базы данных.

Перезагружаем сервер Asterisk и после подключения к консоли сервера проверяем соединение с базой.
cdr mysql status
Connected to asteriskdb@127.0.0.1, port 3306 using table cdr for 1 hours, 22 minutes, 39 seconds.”

Подготовка MySQL таблиц


Итак, настройка сервера произведена и теперь в базе данных MySQL создаём таблицы с требуемыми полями. К сожалению тут не всё так просто, дело в том что от версии к версии Asterisk поля меняются. Те MySQL таблицы которые можно найти в интернете от ранних версий Asterisk уже не подходят к современным версиям Asterisk и приходится их дорабатывать. Ситуация осложняется и тем что дорабатывать приходится даже те MySQL таблицы которые идут вместе с исходным кодом Asterisk и находятся в директории “asterisk-1.8.x.x/contrib/realtime/mysql”. Дело это поправимо, благо изменений в MySQL таблицах много не требуется и готовые к использованию таблицы будут представлены далее.

Asterisk musiconhold realtime


В качестве примера начнём с лёгкого на мой взгляд варианта, такого как перенос значений конфигурационного файла musiconhold.conf в базу данных MySQL. Чтобы создать требуемую таблицу воспользуемся следующей SQL командой:
CREATE TABLE musiconhold (
       name char(80) not null primary key,
       mode char(80) null,
       directory char(255) null,
       application char(255) null,
       digit char(1) null,
       sort char(10) null,
       format char(10) null,
       stamp timestamp
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Рассмотрим по порядку назначение каждого поля. Те значения которые указаны в конфигурационном файле musiconhold.conf будем указывать как значения по умолчанию.

name - имя MOH класса (‘default’ по умолчанию). 
mode - одно из значений “'custom', 'files', 'mp3nb', 'quietmp3nb' или 'quietmp3' (‘files’ по умолчанию)
directory - Указывается директория с файлами которые требуется проигрывать, возможно также указать поток или URL. Если значение mode установлено в ‘custom’ директория игнорируется. (‘/var/lib/asterisk/moh’ по умолчанию)
application - Запускается приложение которое предоставляет MOH в случае если значение mode установлено в ‘custom’. В противном случае игнорируется. (‘null’ по умолчанию)
digit - Цифра соответствующая классу MOH, в том случае если MOH возможно выбрать звонящему абоненту. (‘null’ по умолчанию)
sort - Порядок проигрывания файлов, одно из значений 'random' or 'alpha'. В случае если значение отсутствует устанавливается порядок в котором отображаются файлы в директории. (‘null’ по умолчанию)
format - Указывается формат воспроизводимого аудио файла в случае если значение mode установлено в ‘custom’. Форматом аудио файла по умолчанию является SLIN, “16 bit Signed Linear PCM” (‘null’ по умолчанию)
stamp - Временная метка модификации записи.

После этого в конфигурационном файле musicinhold.conf комментируем все записи, а в конфигурационном файле extconfig.conf напротив, убираем комментарий у записи “musiconhold => mysql,general”. Зайдя на консоль asterisk выполняем команду “module reload”. Перезагрузка модулей требуется для перемещения конфигурации из файла musiconhold.conf в базу данных MySQL.

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

Продолжение рассказа о работе с Asterisk realtime в следующих публикациях которые можно отыскать по тегам.