Используем AUFS для отката изменений. Автоматический возврат системы после перезагрузки Денис Силаков # modprobe aufs # mkdir -p /tmp/dir1/dir-common /tmp/dir2/dir-common /tmp/dir-aufs # touch /tmp/dir1/dir-common/uniq-dir1-file # touch /tmp/dir2/dir-common/uniq-dir2-file # echo "This is dir1 file" > /tmp/dir1/dir-common/common-file # echo "This is dir2 file" > /tmp/dir2/dir-common/common-file # mount -t aufs -o dirs=/tmp/dir2=rw:/tmp/dir1=ro none /tmp/dir-aufs # mount -t aufs -o dirs=/tmp/dir2=rw:/tmp/dir1=ro none /tmp/dir1 #!/bin/bash installkernel() { instmods aufs } install() { inst_hook pre-pivot 10 "$moddir/aufs-mount.sh" } #!/bin/sh mkdir /sysroot/tmp/sysroot-rw mount -n -t tmpfs tmpfs /sysroot/tmp/sysroot-rw mkdir -m 755 "/sysroot/tmp/sysroot-rw/bin" mount -n -t aufs -o dirs=/sysroot/tmp/ sysroot-rw/bin=rw:/sysroot/bin=ro none /sysroot/bin ----------------------------------------------------------------------------------------------------------------- Расширяемся, или Установка MS SCCM для филиалов Сергей Болдин Листинг 1. Запрос на выборку select name, collation_name, is_trustworthy_on, is_broker_enabled, is_honor_broker_priority_on from sys.databases where name = 'СМ_DD' sp_configure 'clr enabled' Листинг 2. Включение параметров USE master; GO ALTER DATABASE CM_DD SET ENABLE_BROKER ON GO USE master; GO ALTER DATABASE CM_DD SET TRUSTWORTHY ON GO USE master; GO ALTER DATABASE CM_DD SET HONOR_BROKER_PRIORITY ON GO Листинг 3. Настройка DHCP-пула ip dhcp pool center //имя DHCP-пула network 192.168.1.0 255.255.255.0 //адрес сети dns-server 192.168.1.5 192.168.1.6 //IP-адреса DNS-серверов domain-name energy.net //имя домена default-router 192.168.1.254 //IP-адрес маршрутизатора по умолчанию option 66 ip 192.168.2.7 //IP-адрес SCCM-сервера option 67 ascii "\SMSBoot\x86\wdsnbp.com" //путь к PXE-загрузчику interface GigabitEthernet0/0 //интерфейс маршрутизатора ip address 192.168.1.254 255.255.255.0 //адрес интерфейса ip helper-address 192.168.2.7 //указывает DHCP-пакетам IP-адрес сервера в иной подсети ----------------------------------------------------------------------------------------------------------------- Восстановление Windows 7, 8, 8.1 до исходного состояния со своими настройками Игорь Решетов C:\Windows\System32\Sysprep\Sysprep.exe /generalize /oobe /shutdown dism /Capture-Image /ImageFile:/G:\Image\install.wim /CaptureDir:C:\ /Name:Win8 SET ID=27 GPT ATTRIBUTES=DE94BBA4-06D1-4D40-A16A-BFD50179D6AC DISKPART sel disk 0 sel part 3 assign reagentc /setosimage /path E:\Image\install.wim /index 1 remove ----------------------------------------------------------------------------------------------------------------- GlusterFS – новый класс хранилищ данных Александр Руденко # yum localinstall -y http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm # wget -P /etc/yum.repos.d http://download.gluster.org /pub/gluster/glusterfs/LATEST/EPEL.repo/glusterfs-epel.repo # yum install glusterfs-server # service glusterd start # chkconfig glusterd on # chkconfig iptables off # service iptables stop # vi /etc/sysconfig/selinux .... SELINUX=disabled .... (вывод сокращен) # gluster peer probe gl02 # gluster volume create rep01 replica 2 gl01: /gluster/gv01 gl02:/gluster/gv01 # gluster volume start rep01 # gluster volume info rep01 # gluster volume add-brick rep01 replica 3 gl01: /gluster/gv03 # gluster volume create distr01 transport tcp gl01: /distr01 gl02:/distr01 # gluster volume add-brick distr01 gl03:/distr01 # gluster volume rebalance distr01 start # gluster volume remove-brick distr01 gl03:/distr01 # gluster volume create dr_rep replica 2 gl01: /dr gl02:/dr gl01:/dr2 gl02:/dr2 # gluster volume add-brick dr_rep replica 2 gl03: /dr3 gl04:/dr3 # gluster volume create dr_rep replica 3 gl01:/dr gl02: /dr gl03:/dr gl01:/dr2 gl02:/dr2 gl03:/dr2 # gluster volume create st_vol stripe 2 gl01: /st_vol gl02:/st_vol # gluster volume stop <имя_тома> # gluster volume delete <имя_тома> # mount gl01:/<имя_тома> /<каталог_монтирования> $ sudo apt-get install glusterfs-client # yum -y install glusterfs glusterfs-fuse # mount.glusterfs gl01:/<имя_тома> /<каталог_монтирования> gl01.mydomain.com:/<имя_тома> /<каталог_монтирования> glusterfs defaults,_netdev 0 0 # yum install -y vdsm-gluster # service vdsm restart # секция, описывающая первый сервер volume rp-client-0 # тип/подтип транслятора type protocol/client option send-gids true option password bdcb0d40-a4b2-40f9-ab7e-404f6eedcf1b option username ce259dd4-ffaf-4cbb-ab80-8419dec5dc67 option transport-type tcp option remote-subvolume /dr option remote-host gl01 end-volume # секция, описывающая второй сервер volume rp-client-1 # тип/подтип транслятора type protocol/client option send-gids true option password bdcb0d40-a4b2-40f9-ab7e-404f6eedcf1b option username ce259dd4-ffaf-4cbb-ab80-8419dec5dc67 option transport-type tcp option remote-subvolume /dr option remote-host gl02 end-volume # топология репликации volume r1-replicate-0 # тип/подтип транслятора type cluster/replicate # реплика с client-0 на client-1 subvolumes r1-client-0 r1-client-1 end-volume # эти параметры определяют, как будут распределяться # поступаемые данные volume r1-dht type cluster/distribute # в нашем случае никак, т.к. том не Distributed subvolumes r1-replicate-0 end-volume ... ... # параметры кэширования volume r1-io-cache # тип/подтип транслятора type performance/io-cache option cache-size 64MB option cache-timeout 4 option max-file-size 2MB subvolumes r1-read-ahead end-volume # gluster volume set <том> <ключ> <значение> # gluster volume set r1 auth.allow 10.200.77.45,10.200.77.46 performance.write-behind-window-size 1073741824 performance.cache-refresh-timeout 1 performance.cache-size 1073741824 performance.read-ahead off # gluster volume quota r1 enable # gluster volume quota r1 limit-usage / 1GB # gluster volume quota r1 limit-usage /test 100MB # gluster volume quota r1 list ----------------------------------------------------------------------------------------------------------------- Почтовые клиенты для Android с поддержкой SSL-сертификатов Рашид Ачилов /usr/local/etc/dovecot/conf/10-auth.conf auth_ssl_require_client_cert = yes /usr/local/etc/dovecot/conf/10-ssl.conf ssl_ca = adb push severtsev-rv_deltahw.p12 /mnt/sdcard ----------------------------------------------------------------------------------------------------------------- Мультипроцессорный Squid Гавриил Каримов # pkg search squid # pkg fetch squid33-3.3.11_2 WITH_PKGNG=yes # make config # make && make install && make clean cache_dir rock DirectoryName Megabytes workers N cache_dir rock /var/squid/cache/rock 400 worker 2 access_log daemon:/var/log/squid/access_kid${process_number}.log squid cache_log /var/log/squid/cache_kid${process_number}.log # squid –z # service squid start # ps ax | grep squid sysctl net.local.dgram.recvspace=262144 sysctl net.local.dgram.maxdgram=16384 ----------------------------------------------------------------------------------------------------------------- Настройка протоколирования CDR на сервере RADIUS и программа обработки CDR-записей Владимир Нефедов copy ftp://имя_пользователя:пароль_пользователя@адрес_FTP_сервера/cdr.txt flash:cdr.txt configure terminal ! Разрешает сервер AAA aaa new-model ! Определяем учет телефонных звонков aaa accounting connection h323 ! Записываем только окончание звонка action-type stop-only ! Записываем на RADIUS-сервер, определенный ниже group radius radius-server host 192.168.88.100 auth-port 1812 acct-port 1813 radius-server domain-stripping radius-server key cisco radius-server vsa send accounting radius-server vsa send authentication call accounting-template voice at-cdr flash:cdr.txt gw-accounting aaa acct-template at-cdr exit exit copy runnig-config startup-config client 192.168.88.86 { secret = cisco shortname = voice-cdr } /usr/local/etc/rc.d/radiusd restart client 192.168.88.86 { secret = cisco shortname = voice-cdr } /usr/local/etc/rc.d/radiusd restart 'ON ERROR RESUME NEXT Dim nRow, nCol, sTxt Dim objExcel, myText, FileSysObj nRow = 1 nCol = 1 sTxt = "" sFile = GetArguments() set FileSysObj = WScript.CreateObject("Scripting.FileSystemObject") set myText = FileSysObj.OpenTextFile(sFile, 1) set objExcel = WScript.CreateObject("Excel.Application") objExcel.WorkBooks.Add objExcel.Cells(nRow, 1).Value = "Идентификатор" objExcel.Columns(1).ColumnWidth = 35 objExcel.Cells(nRow, 2).Value = "АОН" objExcel.Columns(2).ColumnWidth = 15 objExcel.Columns(2).Select objExcel.Selection.NumberFormat = "@" With objExcel HorizontalAlignment = xlLeft VerticalAlignment = xlTop WrapText = True Orientation = 0 AddIndent = False IndentLevel = 0 ShrinkToFit = False ReadingOrder = xlContext MergeCells = False End With nRow = 2 while (not myText.AtEndOfStream) sTxt = myText.ReadLine() sNef = sFilter(sTxt) WEnd myText.Close() objExcel.Columns(1).Select objExcel.Rows("1:1").Select objExcel.Selection.AutoFilter objExcel.Visible = true WScript.Quit() С:\radacct>CScript rad-acct.vbs С:\radacct\detail-20140901 Листинг 1. Скрипт для оброаботки RADIUS-файлов 'ON ERROR RESUME NEXT Dim nRow, nCol, sTxt ‘ Определяем переменные Dim objExcel, myText, FileSysObj nRow = 1 nCol = 1 sTxt = "" Call Main ‘ Запускаем программу Sub Main ‘ Определяем главную программу sFile = GetArguments() ‘ Получаем имя файла ‘ Открываем текстовый файл с CDR-записями на чтение set FileSysObj = WScript.CreateObject("Scripting.FileSystemObject") set myText = FileSysObj.OpenTextFile(sFile, 1) ‘ Создаем таблицу EXCEL set objExcel = WScript.CreateObject("Excel.Application") objExcel.WorkBooks.Add ‘ Создаем поля в таблице с атрибутами objExcel.Cells(nRow, 1).Value = "Идентификатор" objExcel.Columns(1).ColumnWidth = 35 objExcel.Cells(nRow, 2).Value = "АОН" objExcel.Columns(2).ColumnWidth = 15 objExcel.Columns(2).Select objExcel.Selection.NumberFormat = "@" With objExcel HorizontalAlignment = xlLeft VerticalAlignment = xlTop WrapText = True Orientation = 0 AddIndent = False IndentLevel = 0 ShrinkToFit = False ReadingOrder = xlContext MergeCells = False End With nRow = 2 ‘ В цикле читаем файл с CDR-записями и заполняем строки в таблице while (not myText.AtEndOfStream) ‘ Читаем строку в текстовом файле sTxt = myText.ReadLine() ‘ Вызываем программу, которая в качестве аргумента получает строку текстового файла и заносит данные этой строки в таблицу sNef = sFilter(sTxt) Wend ‘ После получения последней строки текстового файла происходит его закрытие myText.Close() objExcel.Columns(1).Select ‘ Установка автофильтра на поля objExcel.Rows("1:1").Select objExcel.Selection.AutoFilter objExcel.Visible = true ‘ Визуализация таблицы EXCEL WScript.Quit() End Sub ‘ Функция sFilter производит разбор строки и помещает значения полей в таблицу Function sFilter(sFlt) Dim asArray, asArray1 ‘ Убираем из строки знаки табуляции sFlt = Replace(sFlt, " ", "") ‘ Разбиваем строку на аргумент и значения. Заносим в массив If ((InStr(sFlt, " =") <> 0)) Then asArray = Split(sFlt, " =" , -1 , 1) sFlt = Trim(asArray(0)) ' WScript.Echo(sFlt) If ((InStr(asArray(1), "=") <> 0)) Then sFlt1 = Replace(asArray(1), Chr(34), "") asArray1 = Split(sFlt1, "=" , -1 , 1) sFlt1 = Trim(asArray1(0)) End If End If ‘ Ищем в массиве аргумент и, найдя его, заносим значение в таблицу Select Case sFlt Case "h323-conf-id" objExcel.Cells(nRow, 1).Value = asArray1(1) Case "Calling-Station-Id" objExcel.Cells(nRow, 2).Value = Replace(asArray(1), Chr(34), "") Case "Called-Station-Id" objExcel.Cells(nRow, 3).Value = Replace(asArray(1), Chr(34), "") Case "h323-setup-time" objExcel.Cells(nRow, 4).Value = asArray1(1) Case "h323-connect-time" objExcel.Cells(nRow, 5).Value = asArray1(1) Case "h323-disconnect-time" objExcel.Cells(nRow, 6).Value = asArray1(1) Case "Acct-Session-Time" objExcel.Cells(nRow, 7).Value = Replace(asArray(1), Chr(34), "") Case "h323-disconnect-cause" objExcel.Cells(nRow, 8).Value = asArray1(1) Case "h323-remote-address" objExcel.Cells(nRow, 10).Value = asArray1(1) Case "NAS-Port-Id" objExcel.Cells(nRow, 13).Value = Replace(asArray(1), Chr(34), "") Case "Cisco-AVPair" Select Case sFlt1 Case "disconnect-text" objExcel.Cells(nRow, 9).Value = asArray1(1) Case "remote-media-address" objExcel.Cells(nRow, 11).Value = asArray1(1) Case "voice-tx-duration" objExcel.Cells(nRow, 12).Value = asArray1(1) End Select Case "Timestamp" nRow = nRow + 1 Case else ' WScript.Echo(sFlt) End Select sFilter = sFlt End Function Private Function GetArguments() strFlag = Empty iCount = 0 If Wscript.Arguments.Count > 0 Then While iCount < Wscript.Arguments.Count strFlag = strFlag & " " & Wscript.arguments.Item(iCount) WScript.Echo(Wscript.arguments.Item(iCount)) iCount = iCount + 1 WEnd End If If IsEmpty(strFlag) Then GetArguments= NULL WScript.Echo("Set to correct path (EXAMPLE c:\name_folder)") WScript.Quit (1) End If GetArguments = Trim(strFlag) End Function h323-gw-id h323-call-origin h323-call-type h323-setup-time h323-connect-time h323-disconnect-time voice-tx-duration tx-duration h323-remote-address h323-voice-quality h323-disconnect-cause disconnect-text session-protocol remote-media-address subscriber acom-level noise-level receive-delay round-trip-delay ontime-rv-playout gapfill-with-silence gapfill-with-prediction gapfill-with-interpolation gapfill-with-redundancy lost-packets early-packets late-packets dsp-id out-carrier-id in-intrfc-desc out-intrfc-desc ----------------------------------------------------------------------------------------------------------------- Отказоустойчивый антивирусный сервер Арсений Анкудинов; Валентина Югай Листинг 1. Программа решения задачи 1 create user drwcs; alter user drwcs password 'хххх'; create database drwcs with owner=drwcs; create database drwcs owner=drwcs encoding='UTF8'; ----------------------------------------------------------------------------------------------------------------- Горизонтальное масштабирование. Проблемы и пути решения Александр Календарев incr('msg_id'); // массив серверов $servers = array('10.0.0.1','10.0.0.2','10.0.0.3', '10.0.0.4','10.0.0.5','10.0.0.6','10.0.0.7',...); // вычисляем номер сервера $server_num = floor($id / SHARD_COUNT); // и собственно сам сервер $server = $servers[$server_num]; // соединяемся с нужным сервером $mysql = mysql_connect($server, ...); $sql = sprintf('INSERT INTO msg_text (id, owner_id, user_id, text) VALUES(%d, %d,%d,%s,)', $id, $owner_id, $user_id, $text); // выполняем вставку данных $q = mysql_query($sql, $mysql); // массив серверов $servers = array( array( ip => '10.0.0.1', count => 3, beg => 0, end => 2), array( ip => '10.0.0.2', count => 5, beg => 3, end => 7), array( ip => '10.0.0.3', count => 2, beg => 8, end => 9), array( ip => '10.0.0.4', count => 5, beg => 10, end => 14), ,...); function getShard($id, $servers) { // вычисляем виртуальный номер таблицы $virt_num = floor($id / SHARD_COUNT); $server_num = 0; // вычисляем физический номер сервера foreach($servers as $server) { $out_server = $server; if ($server['beg'] >= $virt_num && ↵ $server['end'] <= $virt_num ) break; $server_num ++; } $tab_index = $virt_num - $out_server['beg']; return array('num' => $vir_num, 'index' => $tab_index); } // пример использования getShard() $redis = new redis(); // получаем значение msg_id $id = $redis->incr('msg_id'); // вычисляем номер таблицы берем из конфига list($server_num, $tab_index) = getShard($id, $servers); // нужный сервер $server = $servers[$server_num]['ip']; // открываем соединение $mysql = mysql_connect($server, ...); $sql = sprintf("INSERT INTO msg_text_% (id, owner_id, user_id, text) VALUES(%d, %d,%d,'%s',)", $tab_index, $id, $owner_id, $user_id, $text); // выполняем вставку данных $q = mysql_query($sql, $mysql); { servers : [ {'ip' : '10.0.0.1', dbs : [ {'num' : 0, 'count' : 3, 'beg' : 0}, {'num' : 1, 'count' : 5, 'beg' : 10}] }, {'ip' : '10.0.0.2', dbs : [ {'num' : 0, 'count' : 3, 'beg' : 3}, {'num' : 1, 'count' : 5, 'beg' : 15}] }, {'ip' : '10.0.0.3', dbs : [ {'num' : 0, 'count' : 4, 'beg' : 6}] }, ] } $servers = array( '404' => '10.0.0.5', 'msk' => '10.0.0.1', 'spb' => '10.0.0.2', 'nvs' => '10.0.0.3', 'nvg' => '10.0.0.3', ,...); array( ... '404' => array( host=>'10.0.0.1', 'port'=>3306, 'shema'=>'city_0', 'table'=> 0 ), 'msk' => array( host=>'10.0.0.1', 'port'=>3307, 'shema'=>'city_1', 'table'=> 0 ), 'spb' => array( host=>'10.0.0.2', 'port'=>3306, 'shema'=>'city_0', 'table'=> 0 ), 'nvs' => array( host=>'10.0.0.2', 'port'=>3306, 'shema'=>'city_0', 'table'=> 1 ), ); "SELECT * FROM `%Db`.`my_table_%T` WHERE ..." function sql_builder( $sql_template, $city, $config) { $city_conf = isset($config[$city]) ? $config[$city]: $config['404']; $res = str_replace($sql_template, '%Db', $city_conf['schema'] ); $res = str_replace($res, '%T', $city_conf['table'] ); return array('sql' =>$res, 'host' => $city_conf['host'], 'port', => $city_conf['port']); } // пример использования $sql_template="INSERT INTO`%D.city_%T` (tel_num, city, region_id) VALUES(%d,'%s', %d)"; // строим SQL с учетом таблицы и схемы $sql_buid = sql_builder($sql_template, 'msk', $config); // строим SQL с учетом используемых данных $sql = sprintf($sql_buid['sql'], $num, $city, $region_id); // соединяемся с нужным сервером $mysql = mysql_connect($sql_buid['host'], $sql_buid['port']); // выполняем запрос $q = mysql_query($sql, $mysql); define('SERVERS_COUNT', ...); function getShard($id){ return $id % SERVERS_COUNT; } // массив серверов $servers = array('10.0.0.1','10.0.0.2','10.0.0.3','10.0.0.4','10.0.0.5','10.0.0.6','10.0.0.7',...); // вычисляем номер сервера $server_num = getShard($user_id) ; // и собственно сам сервер $server = $servers[$server_num]; // соединяемся с нужным сервером $mysql = mysql_connect($server, ...); // выполняем запрос $q = mysql_query($sql, $mysql); crc32( $key ) % SERVERS_COUNT; // новое количество серверов define('SERVERS_COUNT_NEW', SERVERS_COUNT_NEW +2); // X= id, когда вставили новые ноды define('X', …); function getShard($id){ if ($id < X ) return $id % SERVERS_COUNT; return $id % SERVERS_COUNT_NEW; } { servers : [ {'ip' : '10.0.0.1', port : 3306, shards : [ {'num' : 0, 'weght': 10, 'name' : 'db0'}, {'num' : 1, 'weght': 10, 'name' : 'db1'}] }, {'ip' : '10.0.0.2', port : 3307, shards : [ {'num' : 2, 'weght': 10, 'name' : 'db0'}, {'num' : 3, 'weght': 10, 'name' : 'db1'}] }, {'ip' : '10.0.0.3', port : 3306, shards : [ {'num' : 4, 'weght': 30, 'name' : 'db0'}] }, ] } //разберем конфигурацию $servers = json_decode($json_servers); $shards = array(); $weght_sum = 0; $shards_count = 0; foreach($servers as $server) { foreach($dbs as $shard) { // получаем общий вес $weght_sum += $shard['weght']; // формируем массив шард $shards[$shard['num']] = $array( 'ip' => $server['ip']; 'port' => $server['port']; 'db' => $shard['name']; ); $shards_count ++; } } foreach($shards as &$shard) { // получаем удельный вес каждой шарды $shard['wegth'] = $shard['wegth'] / $weght_sum; } $shards ['count'] = $shards_count; //генерация shard_id в соответствии с весом шарды function getShardId($shards) { srand(microtime(true)); $number = rand(0,$shards ['count']) / $shards ['count']; $sum = 0; $num = 0; foreach($shards as $shard) { $sum += $shards['weght']; if ($sum > $number) break; $num ++; } return $num; } //построитель запросов function sql_builder( $sql_template, $shard_id, $shards) { $shard = isset($shards[$shard_id]) ? $shards[$shard_id] : null; if (!$shard) throw Exception("error shard_id"); $res = str_replace($sql_template, '%Db', $shard['db'] ); return array('sql' =>$res, 'shard' => $shard); } $shard_id = getShardId($shards); // у нас должно быть общее key/value-хранилище $redis = new redis(); // в котором хранится соответствие $id и $shard_id $redis->set( $id, $shard_id ); // формируем запрос на вставку данных $sql_template = "INSERT INTO `%Db`.users (user_id, shard_id, login,name) VALUES(%d,%d,'%s','%s')"; list($sql, $db) = sqlBuilder ($sql_template, $shardId , $shards); $sql = sprintf($sql, $user_id, $shard_id, $login, $userName); // соединяемся с нужным сервером $mysql = mysql_connect($db['ip'], $db['port']); // выполняем запрос $q = mysql_query($sql, $mysql); // пример на чтение данных //находим shard_id $redis = new redis(); $shard_id = $redis->get($user_id); // формируем запрос на чтение данных $sql_template = "SELECT * FROM `%Db`.users WHERE user_id=%d"; list($sql, $db) = sqlBuilder ($sql_template, $shardId , $shards); $sql = sprintf($sql, $user_id); // выполняем соединение с нужным сервером $mysql = mysql_connect($db['ip'], $db['port']); // выполняем запрос $q = mysql_query($sql, $mysql); { servers : [ {'group' : 'message', 'databases' : [ {'ip' : '10.0.0.1', port : 3306, shards : [ {'num' : 0, 'weght': 10, 'name' : 'db0'}, {'num' : 1, 'weght': 10, 'name' : 'db1'}] }, {'ip' : '10.0.0.2', port : 3307, shards : [ {'num' : 2, 'weght': 10, 'name' : 'db0'}, {'num' : 3, 'weght': 10, 'name' : 'db1'}] }, {'ip' : '10.0.0.3', port : 3306, shards : [ {'num' : 4, 'weght': 30, 'name' : 'db0'}] } ]}, { 'group' : 'profile', 'databases' : [ {'ip' : '10.0.0.4', port : 3306, shards : [ {'num' : 0, 'weght': 10, 'name' : 'db0'}, {'num' : 1, 'weght': 10, 'name' : 'db1'}] }, {'ip' : '10.0.0.5', port : 3307, shards : [ {'num' : 2, 'weght': 10, 'name' : 'db0'}, {'num' : 3, 'weght': 10, 'name' : 'db1'}] }, ]}, {'group' : 'blogs', 'databases' : [ ...]} ] } ----------------------------------------------------------------------------------------------------------------- ASP NET MVC. Веб-приложения самостоятельного размещения Михаил Ушаков PM> Install-Package Microsoft.AspNet.WebApi.Client -Version 4.0.30506 PM> Install-Package Microsoft.AspNet.WebApi.Core -Version 4.0.30506 PM> Install-Package Microsoft.AspNet.WebApi.SelfHost -Version 4.0.30506 namespace Kryptonite.IntegrationalTests.Utils { public class SimpleAssemblyResolver : IAssembliesResolver { public SimpleAssemblyResolver(IList assemblies) { _assemblies = new List(); if(assemblies == null) throw new ArgumentNullException("assemblies"); _assemblies = assemblies; } public ICollection GetAssemblies() { IList assemblies = new List(); foreach (String assembly in _assemblies) assemblies.Add(Assembly.Load(assembly)); return assemblies; } private readonly IList _assemblies; } } assemblies.Add(Assembly.LoadFrom(Path.GetFullPath(assembly))); class Program { static void Main(string[] args) { const String baseAddress = "http://localhost:8989"; String myAssembly = Path.GetFullPath(@"..\..\MyServices\MyService.Rest.dll"); SimpleAssemblyResolver resolver = new SimpleAssemblyResolver(new List() {myAssembly}); HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(baseAddress); config.Services.Replace(typeof(IAssembliesResolver), resolver); config.Routes.MapHttpRoute("DefaultApi", "api/1.0/{controller}", new { id = RouteParameter.Optional }); HttpSelfHostServer server = new HttpSelfHostServer(config); Console.WriteLine("Waiting for clients"); // Start listening server.OpenAsync().Wait(); Console.ReadLine(); server.CloseAsync().Wait(); } } "api/1.0/{controller}/{action}" @ SET APP_PORT=8989 @ SET APP_URL=http://+:%APP_PORT%/ @ SET DOMAIN=mydomain @ SET DOMAIN_USER=ushakov_mv @ SET APP_USER=%DOMAIN%\%DOMAIN_USER% netsh http add urlacl url=%APP_URL% user=%APP_USER% Type assemblyType = typeof(NewServiceController); Assembly assembly = assemblyType.Assembly; public partial class HttpApiService : ServiceBase { public HttpApiService() { InitializeComponent(); _config = new HttpSelfHostConfiguration(ServiceAddress); _config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }); } protected override void OnStart(string[] args) { _server = new HttpSelfHostServer(_config); _server.OpenAsync(); } protected override void OnStop() { _server.CloseAsync().Wait(); _server.Dispose(); } private HttpSelfHostServer _server; private readonly HttpSelfHostConfiguration _config; public const String ServiceAddress = "http://localhost:2345"; } [SetUp] public void SetUp() { SimpleAssemblyResolver resolver = new SimpleAssemblyResolver(new[] { KryptoniteAssembly }); HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(BaseAddress); config.Services.Replace(typeof(IAssembliesResolver), resolver); config.Routes.MapHttpRoute("DefaultApi", RouteSchema, new { id = RouteParameter.Optional }); _server = new HttpSelfHostServer(config); _server.OpenAsync().Wait(); } [TearDown] public void TearDown() { _server.CloseAsync().Wait(); _server.Dispose(); _server = null; // db cleanup } private LoginDataCollection ReadLoginDataCollectionFromJson() { LoginDataCollection jsonLoginCollection; using (WebClient webClient = new WebClient()) webClient.Headers.Add("Content-Type", "application/json"); webClient.Headers.Add("Charset", "utf-8"); { using (Stream stream = webClient.OpenRead(_loginsUri)) { if (stream == null) throw new InvalidOperationException("Stream is null!"); using (StreamReader streamReader = new StreamReader(stream)) { String responceLine = streamReader.ReadToEnd(); Assert.IsFalse(String.IsNullOrEmpty(responceLine), "Check if line is not empty"); jsonLoginCollection = (LoginDataCollection)JsonConvert.DeserializeObject(responceLine, typeof(LoginDataCollection)); } } } return jsonLoginCollection; } String authenticationRequestJson = JsonConvert. SerializeObject(request); using (WebClient webClient = new WebClient()) { webClient.Headers.Add("Content-Type", "application/json"); webClient.Headers.Add("Charset", "utf-8"); String responceLine = webClient.UploadString(_authenticationUri, "POST", authenticationRequestJson); AuthenticationResult actualResult = (AuthenticationResult) JsonConvert.DeserializeObject(responceLine, typeof(AuthenticationResult)); ResultCheckers.Check(expectedResult, actualResult); } webClient.QueryString.Add(IdParameter, id.ToString()); private const String IdParameter = "id"; [TestCase("not a guid", HttpStatusCode.BadRequest)] [TestCase("1.12345678900987654321", HttpStatusCode.BadRequest)] [TestCase(NonExistingLoginId, HttpStatusCode.NotFound)] public void TestGetLoginFails(String id, HttpStatusCode statusCode) { using (WebClient webClient = new WebClient()) { webClient.Headers.Add("Charset", "utf-8"); webClient.QueryString.Add(IdParameter, id); try { webClient.DownloadString(_loginsUri); } catch (WebException webException) { Assert.AreEqual(((HttpWebResponse) webException.Response).StatusCode, statusCode); } } } String responceLine = webClient.UploadString(_profilesUri, "POST", profileJson); String responceLine = webClient.UploadString(_profilesUri, "DELETE", String.Empty); ----------------------------------------------------------------------------------------------------------------- Пакет программ XMD. Физические эксперименты за компьютером Cергей Ильичев POTENTIAL PAIR 1 1 2000 1.2 6.3 Листинг 1. Выдержки из файла fefarkas.txt eunit K calc A0=2.87 calc MassFe=55.85 calc DTIME=1e-16 dtime DTIME POTENTIAL SET EAM 1 POTENTIAL PAIR 1 1 3000 9.920413E-01 4.095403E+00 8.935990E+04 8.920155E+04 8.904339E+04 8.888540E+04 8.872760E+04 8.856996E+04 8.841251E+04 8.825523E+04 8.809813E+04 8.794121E+04 8.778446E+04 8.762789E+04 ... POTENTIAL DENS 1 3000 9.920410E-01 4.095400E+00 1.641865E+00 1.636743E+00 1.631639E+00 1.626552E+00 1.621483E+00 1.616432E+00 1.611398E+00 1.606382E+00 1.601382E+00 1.596400E+00 1.591436E+00 ... POTENTIAL EMBED 1 3000 3.398751E-02 3.315712E+00 -1.974536E+04 -1.994018E+04 -2.012917E+04 -2.031256E+04 -2.049056E+04 -2.066335E+04 -2.083112E+04 -2.099404E+04 -2.115229E+04 -2.130600E+04 -2.145533E+04 -2.160042E+04 ... CALC x = 2^(1/3) POTENTIAL SET EAM 1 #Чтение файла потенциалов read fefarkas.txt #построение ОЦК решетки железа box 5 5 5 fill particle 2 1 0 0 0 1 1/2 1/2 1/2 fill go #постоянная решетки scale A0 select all mass MassFe select ellipse 14 0 14 5 5 5 extforce 0 0.2e-3 0 clamp 800 itemp 800 repeat 10 команда 1 команда 2 end Листинг 2. Файл XMD-программы afe_piece.xm #Чтение файла потенциалов read fefarkas.txt #построение ОЦК решетки железа box 5 5 5 fill particle 2 1 0 0 0 1 1/2 1/2 1/2 fill go # постоянная решетки scale A0 # установим массы частиц select all # MassFe определена в файле fefarkas.txt mass MassFe # установим случайные скорости для атомов, соответствующие температуре 800 K clamp 800 itemp 800 # создаем .cor-файл, записываем начальные координаты частиц write cor fewithextforce.cor # выделение области для применения внешнего воздействия select ellipse 14 0 14 5 5 5 # на выбранные частицы действует внешняя сила extforce 0 0.2e-3 0 # выбираем частицу с номером 210 select index 210 # запись выбранных параметров в начальный момент в файл 210.temp write file 210.temp sel var i tm ek ep # цикл из 600*10 шагов моделирования repeat 600 cmd 10 write file +210.temp sel var i tm ek ep vx write cor +fewithextforce.cor end xmd afe_piece.xm xmdview fewithextforce.cor Листинг 3. Выдержки из файла 210.temp VAR i tm ek ep vx 1 210 1.116965e+03 1.675447e+03 -4.966887e+04 5.0737e+04 210 1.125387e+03 1.688080e+03 -4.966803e+04 5.0661e+04 210 1.134754e+03 1.702132e+03 -4.966241e+04 5.0553e+04 210 1.145665e+03 1.718497e+03 -4.965199e+04 5.0426e+04 .... ----------------------------------------------------------------------------------------------------------------- Головоломка «Отшельник». Реализации решения «выигрывающих стратегий» Кирилл Ткаченко Листинг 1. Исходный код программы для получения всех возможных перестановок направлений public class PegSolPerestanovki { private static final String[] namesForNumbers = new String[] { "-1", "-N", "+1", "+N" }; private static int[] c = new int[] { 0, 1, 2, 3 }; private static void nextPermutation() { final int cveg = c.length - 1; int i, j; int temp; for (i = cveg - 1; c[i] >= c[i + 1]; i--) { } for (j = cveg; c[j] <= c[i]; j--) { } temp = c[i]; c[i] = c[j]; c[j] = temp; i++; for (j = cveg; i < j; i++, j--) { temp = c[i]; c[i] = c[j]; c[j] = temp; } } public static void main(String[] args) { final int konets = 2 * 3 * 4 - 1; for (int i = 0; i <= konets; i++) { System.out.print("int{"); System.out.print(namesForNumbers[c[0]]); System.out.print(", "); System.out.print(namesForNumbers[c[1]]); System.out.print(", "); System.out.print(namesForNumbers[c[2]]); System.out.print(", "); System.out.print(namesForNumbers[c[3]]); System.out.println("}"); if (i < konets) { nextPermutation(); } } } } Листинг 2. Реализация на языке программирования Си #pragma comment(linker, "/STACK:16777216") #include #include #include const char PEG = 'x'; const char HOLE = '-'; #define line 12 const int directions[] = { -1, -line, 1, line }; char firstBoard[] = "...........\n" "...........\n" "....xxx....\n" "....xxx....\n" "..xxxxxxx..\n" "..xxx-xxx..\n" "..xxxxxxx..\n" "....xxx....\n" "....xxx....\n" "...........\n" "...........\n"; int board_length; int noOfTests = 0; int canMove(char board[], int position, int direction) { noOfTests++; return board[position] == PEG && board[position + direction] == PEG && board[position + 2 * direction] == HOLE; } void makeMove(char board[], int position, int direction) { board[position] = HOLE; board[position + direction] = HOLE; board[position + 2 * direction] = PEG; } void removeMove(char board[], int position, int direction) { board[position] = PEG; board[position + direction] = PEG; board[position + 2 * direction] = HOLE; } int solve(char board[]) { int position, direction, idir; int isSolved; int pegsOnBoard = 0; for (position = 0; position < board_length; position++) { if (board[position] == PEG) { pegsOnBoard++; for (idir = 0; idir < 4; idir++) { direction = directions[idir]; if (canMove(board, position, direction)) { makeMove(board, position, direction); isSolved = solve(board); removeMove(board, position, direction); if (isSolved) { puts(board); return 1; } } } } } if (pegsOnBoard == 1) { puts(board); return 1; } return 0; } int main(int argc, char * argv[]) { board_length = strlen(firstBoard); if (!solve(firstBoard)) { puts("There is no solution."); } printf("Number of tests: %d\n", noOfTests); return EXIT_SUCCESS; } Листинг 3. Реализация на языке программирования Java public class PegSolitaireSolverJava { private final char PEG = 'x'; private final char HOLE = '-'; private final int line = 12; private final int[] directions = new int[] { -1, -line, 1, line }; private final StringBuffer firstBoard = new StringBuffer("...........\n" + "...........\n" + "....xxx....\n" + "....xxx....\n" + "..xxxxxxx..\n" + "..xxx-xxx..\n" + "..xxxxxxx..\n" + "....xxx....\n" + "....xxx....\n" + "...........\n" + "...........\n"); private static int noOfTests = 0; private boolean canMove(StringBuffer board, int position, int direction) { noOfTests++; return board.charAt(position) == PEG && board.charAt(position + direction) == PEG && board.charAt(position + 2 * direction) == HOLE; } private void makeMove(StringBuffer board, int position, int direction) { board.setCharAt(position, HOLE); board.setCharAt(position + direction, HOLE); board.setCharAt(position + 2 * direction, PEG); } private void removeMove(StringBuffer board, int position, int direction) { board.setCharAt(position, PEG); board.setCharAt(position + direction, PEG); board.setCharAt(position + 2 * direction, HOLE); } private boolean solve(StringBuffer board) { int pegsOnBoard = 0; for (int position = 0; position < board.length(); position++) { if (board.charAt(position) == PEG) { pegsOnBoard++; for (int direction : directions) { if (canMove(board, position, direction)) { makeMove(board, position, direction); boolean isSolved = solve(board); removeMove(board, position, direction); if (isSolved) { System.out.println(board. toString()); return true; } } } } } if (pegsOnBoard == 1) { System.out.println(board.toString()); return true; } return false; } public PegSolitaireSolverJava() { if (!solve(firstBoard)) { System.out.println("There is no solution."); } System.out.println("Number of tests: " + noOfTests); } public static void main(String[] args) { new PegSolitaireSolverJava(); } } Листинг 4. Реализация на языке программирования Pascal Program PegSolitaireSolverPascal; Const PEG = 'x'; HOLE = '-'; line = 12; directions: array [0..3] Of integer = (-1, -line, 1, line); Var board: string; noOfTests: longint; Function canMove(position: integer; direction: integer): boolean; Begin inc(noOfTests); canMove := (board[position] = PEG) And (board[position + direction] = PEG) And (board[position + 2 * direction] = HOLE); End; Procedure makeMove(position: integer; direction: integer); Begin board[position] := HOLE; board[position + direction] := HOLE; board[position + 2 * direction] := PEG; End; Procedure removeMove(position: integer; direction: integer); Begin board[position] := PEG; board[position + direction] := PEG; board[position + 2 * direction] := HOLE; End; Function solve: boolean; Var position: integer; direction: integer; idir: integer; isSolved: boolean; pegsOnBoard: integer; Begin pegsOnBoard := 0; For position := 1 To length(board) Do Begin If board[position] = PEG Then Begin inc(pegsOnBoard); For idir := 0 To 3 Do Begin direction := directions[idir]; If canMove(position, direction) Then Begin makeMove(position, direction); isSolved := solve(); removeMove(position, direction); If isSolved Then Begin writeln(board); solve := true; exit; End; End; End; End; End; If pegsOnBoard = 1 Then Begin writeln(board); solve := true; exit; End; solve := false; End; Begin board := '...........'#10'...........'#10 + '....xxx....'#10'....xxx....'#10 + '..xxxxxxx..'#10'..xxx-xxx..'#10 + '..xxxxxxx..'#10'....xxx....'#10 + '....xxx....'#10'...........'#10 + '...........'#10; noOfTests := 0; If not solve() Then Begin writeln('There is no solution.'); End; writeln('Number of tests: ', noOfTests); End. -----------------------------------------------------------------------------------------------------------------