понедельник, августа 30

Zend Framework XML-конфиг и константы

В предыдущем посту я написал про то, как легко перейти с INI-конфигурации на XML-конфигурацию. В использовании оной есть как плюсы, так и минусы.

из плюсов, как минимум то, что не приходится писать кучу повторяемых "веток" вида "resources.frontController" - мы пишем простое XML-дерево.
из минусов:
1) чтение XML-конфигурации несколько дольше (по тестам, что нашёл - ~0,15 сек). но есть подозрение, что ещё быстрее, чем ini-файл будет подсовывание напрямую массива как конфигурации
2) При автоматическом форматировании XML в редакторах, значения с zf-константами форматируются "криво" - переносятся на новые строки.

Решением проблемы (2) мы и займёмся.
Для начала скажу, что для разработки я использую Eclipse, а для загрузки файлов на сервер - ant-скрипт, который делает предварительную сборку файлов перед загрузкой на сервер. В нём же производятся некоторые действия над файлами, одно из которых я приведу ниже.

Определим правило, что константы вместо "<zf:const zf:name="константа">" в xml-конфиге будем описывать как "%ZF.константа%". для замены содержимого в файле, воспользуемся task-ом replaceregexp, выглядящий следущим образом:

<replaceregexp flags="g">
 <!-- заменяем "%ZF.константа%" на "<zf:const zf:name="константа" />" -->
 <regexp pattern="%ZF.(.*)%" />
 <substitution expression="&lt;zf:const zf:name=&quot;\1&quot; /&gt;" />
 <fileset dir="${target}/application/configs" includes="**/*.xml" />
</replaceregexp>

собственно на этом всё. :)
Итого: на этапе разработки мы получаем удобный XML, без "лишних" тегов, а на сервере правильный xml-конфиг с понятными для ZF константами

Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

Zend Framework и XML конфиг вместо INI

Делается всё просто как на 1-2-3:

1) открываем файл public/index.php
2) после строки "require_once 'Zend/Application.php';" дописываем строку "require_once 'Zend/Config/Xml.php';"
3) вместо
$application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
пишем строки:
$cfg = new Zend_Config_Xml(APPLICATION_PATH . '/configs/application.xml', APPLICATION_ENV);
$application = new Zend_Application(APPLICATION_ENV, $cfg->toArray());
4) сохраняем изменения

да, и не забываем создать xml-файл конфигурации вместо ini-файла ;)


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

суббота, августа 21

NAT & iptables в Linux (CentOS)

несколько часов убились мною и моим коллегой "по цеху" на поиск решения "да что за нафиг такой?" :)

преамбула:
на сервере используется скрипт iptables.sh, который описывает правила для iptables. дело нехитрое - поправил правила, запустил, проверил работу и, если всё тип-топ, то сохранил правила.
В скрипте описание довольно нехитрое: очистили все правила маршрутизации и воссоздали их по новой.
Всё казалось бы просто, до тех пор, пока не столкнулись с nat-маршрутизацией :)

правила сбрасывались следующими строчками в скрипте:
$IPTABLES -F
$IPTABLES -X
, где $IPTABLES - путь до приложения (IPTABLES="/sbin/iptables")

в том же скрипте когда-то была настройка на переброс порта с 80 на 8080, от которой по некоторым соображениям, было решено отказаться.
дело не хитрое - заремили нужную строку и выполнили скрипт.
и, как говорится, "скоро сказка сказывается, да не скоро дело делается" - НЕ ПАШЕТ.
снова смотрим скрипт - всё верно. сохраняем правила, перегружаем сервер на всякий, что должно как минимум сбросить нам все правила и реанимировать их из сохраняшки. ага, щаз...

в общем, пока суд да дело, было найдено решение - в блок сброса таблицы маршрутизации требуется дописать отдельное правило для сброса именно nat-маршрутов:
$IPTABLES -t nat -F

после чего, весь блок сброса приобретает вид:
$IPTABLES -F
$IPTABLES -X
$IPTABLES -t nat -F

ЗЫ: подумалось, что это ведь довольно неплохая задачка для вопроса на собеседовании :)


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

суббота, августа 14

плюшки Windows 7: список "программы и компоненты"

В показываемом списке работает комбинация Ctrl+R, обновляющая список. удобно - не нужно закрывать и заново открывать, чтобы увидеть свежеустановленное ПО
Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

среда, августа 11

Firefox (NoScript) и IBM PartnerWorld = XSS скриптинг

В какой-то момент, понадобилось добраться до ПО, доступного по партнёрской программе.
Захожу на сайт IBM, авторизуюсь, перехожу в раздел PartnerWorld. Иду в раздел "поиск и загрузка ПО" и... "а с платформы говорят"... в общем, получаю ошибку 503.

Первая мысль - что-то не то с учетной записью. Позвонил в IBM - выяснили, что всё нормально.
Начинаю изыскания на своей стороне.

После непродолжительного анализа, выясняется, что серверов-то у IBM многа и при сёрфинге по сайту, мы "скачем" с одного на другой и в итоге получаем подозрение на XSS-атаку, которую успешно блокирует плагин NoScript.

Чтобы этого не возникало, достаточно в настройки NoScript в разделе XSS (Дополнительно>XSS) добавить правило "^https?://.+\.ibm\.com/*" и, хвала!, всё заработало!


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

воскресенье, августа 1

декоратор Sitemesh и страница ошибок

в предыдущем посте я написал как сделать обработку ошибок через Springframework

В своих проектах я использую Sitemesh для задания шаблонов дизайна для различных страниц.
Для страницы с ошибкой порой требуется её обработка в стандартном шаблоне дизайна. Что делать? рисовать дизайн заново? или можно воспользоваться тем, что предоставляет нам Sitemesh?
Конечно же, предпочтительнее последний вариант.
на FAQ-странице есть указание, что это можно сделать, но там присутствует ошибка - указаны не все диспетчеры для обработки. В список диспетчеров требуется добавить ERROR:

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>ERROR</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

показ страницы ошибки с использованием Spring MVC

При разработке под веб, на "боевых" серверах требуется прятать сообщения об ошибках (ну или хотя бы их как-то "облагораживать").
Стандартный путь - описание обрабатываемых ошибок в web.xml. например такой:
<error-page>
 <error-code>404</error-code>
 <location>/error.jsp</location>
</error-page>
<error-page>
 <exception-type>java.lang.Exception</exception-type>
 <location>/error.jsp</location>
</error-page>

А что делать, если в проекте используется Springframework и хотелось бы использовать его возможности?
Всё достаточно просто. Требуется написать контроллер, который будет обрабатывать урл например вида "/error.htm" и в web.xml вместо "/error.jsp" указать "/error.htm" - код и сообщение об ошибке по прежнему будут нам доступны в объекте request.

Зачем это нужно, спросите вы? Например это позволит автоматически сформировать сообщение администратору системы о возникшем сбое, или добавить логику для обработки возникшей ошибки.

среда, июля 28

Релиз дистрибутива Clonezilla Live 1.2.5

Вышел стабильный релиз Linux дистрибутива Clonezilla Live 1.2.5-35, предназначенного для быстрого клонирования дисков (копируются только используемые блоки). Задачи выполняемые дистрибутивом сходны с проприетарным продуктом Norton Ghost. Дистрибутив основан на Debian GNU/Linux, в своей работе использует код проектов DRBL, Partition Image, ntfsclone, partclone, udpcast. Возможна загрузка с CD, USB Flash и по сети (PXE). Поддерживаются ФС: ext2, ext3, reiserfs, reiser4, xfs, jfs, FAT, NTFS, UFS, HFS+ (Mac OS X). Поддерживается режим массового клонирования в multicast режиме, например, при тестировании, за 10 минут удалось провести клонирование исходного 5.6 Гб диска на 41 клиентскую машину. Размер iso-образа дистрибутива - 118 Мб.

Из наиболее заметных улучшений релиза Clonezilla Live 1.2.5-35 можно отметить:

  • Дистрибутив переведен на пакетную базу Debian Sid, со всеми обновлениями по состоянию на 20 июля;
  • Linux-ядро обновлено до версии 2.6.32-17;
  • Для сборки Live-системы использованы пакеты live-helper 2.0~a19-1.1drbl и live-initramfs 1.236.2-1drbl-3;
  • Утилита Partclone обновлена до версии 0.2.11;
  • По умолчанию используется видеорежим VGA 800x600, что позволяет использовать дистрибутив на нетбуках с небольшими экранами;
  • В приложение prep-ocsroot добавлена поддержка sshfs/cifs путей с пробелами;
  • Программа ocs-iso теперь может создавать iso для восстановления системы, размером больше 4.5 Гб.




источник

Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

понедельник, июля 26

скорость загрузки сайта и Google ajaxlibs

Собственно, отказался от использования Google ajaxLibs, т.к. сайты его использующие, открывались достаточно долго. задержка загрузки порядка +3-4 секунды.
Перетащил всё на собственный CDN-сервер.
Думаю ещё попробовать CDN от Yandex - сравню скорость загрузки с ним.


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

воскресенье, июля 4

Maven2 и несколько серверов для WAR-архива. часть 1: работа с зависимостями

Предистория:
С недавних пор решил перебраться с Ant на Maven. Причины? они просты - в Maven неплохо реализована работа с зависимостями (которую я активно использую в Eclipse), но мне было неудобно каждый раз выискивать и копировать эти зависимости ручками на сервер (что тестовый, что "боевой"). В итоге было решено перебраться полностью. А там, где возможностей не хватает, то использовать Antrun плагин, позволяющий использовать ant-скрипты.

Итак, лирика закончилась. Приступим к реализации цели поста.

Имеется исходная задача:
1) набор зависимостей для проекта (здесь и далее подразумевается разработка WAR-архива)
2) "боевой" удалённый сервер
3) тестовый удалённый сервер (отличается от "боевого" настройками для отладки)
4) на серверах установлен Tomcat6 с настроенной поддержкой shared-lib


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

Для определения dependency-библиотек, которые будут копироваться в shared-каталог tomcat, будем использовать указание scope как provided (подробнее про scope читать на русском тут)

Несколько продолжительные изыскания привели к следующей схеме профилей:

  • профиль "development" - указываем свойства, специфичные для сервера разработки, такие как пути и логины/пароли
  • профиль "production" - указываем свойства, специфичные для "боевого" сервера (всё те же пути и логины/пароли)
  • профиль "dependency" - в этом профиле описываем плагины (и их работу), отвечающие за копирование зависимостей на выбранный сервер
пример профиля "development" (для профиля "production" подставляются другие значения свойств):
<profile>
 <id>development</id>
 <properties>
  <hostname>servername.dev</hostname>
  <ssh.host>${hostname}</ssh.host>
  <ssh.username>логин</ssh.username>
  <ssh.password>пароль</ssh.password>
  <ssh.tomcat.lib.shared>/srv/tomcat/shared/lib</ssh.tomcat.lib.shared>
 </properties>
</profile>

Теперь перейдём к самому "сложному" - копированию зависимостей на сервер.
для этого потребуется 2 шага - сбор зависимостей и, собственно, само их копирование.

Для сбора зависимостей, воспользуемся плагином maven-dependency-plugin, для которого укажем некоторые нюансы его работы:
<plugin>
 <artifactId>maven-dependency-plugin</artifactId>
 <version>2.1</version>
 <executions>
  <execution>
   <id>10-copy-dependencies</id>
   <phase>process-resources</phase>
   <goals><goal>copy-dependencies</goal></goals>
   <configuration>
    <IncludeScope>provided</IncludeScope>
    <outputDirectory>${project.build.directory}/dependency</outputDirectory>
    <overWriteReleases>false</overWriteReleases>
    <overWriteSnapshots>false</overWriteSnapshots>
    <overWriteIfNewer>true</overWriteIfNewer>
   </configuration>
  </execution>
 </executions>
</plugin>

Кратко поясню, что здесь написано.
1) указано выполнение плагина с моими настройками на этапе работы с ресурсами (process-resources) проекта. подробнее про Lifecicle проекта можно глянуть тут
2) указываем, какие (IncludeScope) и куда (outputDirectory), а так же режим копирования

Теперь перейдём к шагу копирования полученных зависимостей на удалённый сервер. Для этого воспользуемся ant задачей scp
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-antrun-plugin</artifactId>
 <version>1.4</version>
 <executions>
  <execution>
   <id>90-antrun-copy-dependencies</id>
   <phase>process-resources</phase>
   <goals><goal>run</goal></goals>
   <configuration>
    <tasks>
     <scp todir="${ssh.username}@${ssh.host}:${ssh.tomcat.lib.shared}" 
      password="${ssh.password}">
      <fileset dir="target/dependency" />
     </scp>
    </tasks>
   </configuration>
  </execution>
 </executions>
 <dependencies>
  <dependency>
   <groupId>ant</groupId>
   <artifactId>ant-jsch</artifactId>
   <version>1.6.5</version>
  </dependency>
  <dependency>
   <groupId>com.jcraft</groupId>
   <artifactId>jsch</artifactId>
   <version>0.1.42</version>
  </dependency>
 </dependencies>
</plugin>

Кратко поясню, что здесь написано:
1) Указано выполнение плагина maven-antrun-plugin с моими настройками на этапе работы с ресурсами (process-resources) проекта
2) Для выполнения плагина подключены необходимые зависиимости, доступные только на этапе работы плагина (требуются для scp-задачи)

Теперь описанные выше два плагина мы добавляем в профиль "dependency" следующим образом:
<profile>
 <id>copy-dependency</id>
 <build>
  <finalName>${hostname}</finalName>
  <plugins>
   <plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    ...
   </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-antrun-plugin</artifactId>
     ...
   </plugin>
  </plugins>
 </build>
</profile>

На этом конфигурирование Maven для проекта закончилось.

Следующий шаг - настройка запуска сборок в eclipse для проекта maven.
воспользуемся плагином m2eclipse и в диалоге Run>Run configurations... создадим 2 конфигурации:




В профиле мы указываем сразу 2 профиля - один (например "development") используется для предоставления свойств, а второй ("dependency") реализует процедуру копирования зависимостей на сервер согласно указанных свойств
Так же мы указываем 2 шага выполнения Maven - clean (очистка от предыдущей сборки) и работу с ресурсами (process-resources).

Итог:
создавая и комбинируя различные профили, можно добиться практически такой же гибкости как у Ant, при этом Maven "заставляет" нас придерживаться строгой структуры каталогов (что тоже можно немного изменить) и последовательностей сборки проекта.

Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!