Миграция

Иногда возникает необходимость продолжать работу над старыми проектами, в которых могут использоваться устаревшие системы версий — например, mercurial или, боже упаси, svn. К счастью, для перехода с mecurial на git не требуется начинать проект с чистого листа и терять историю изменений, есть утилита, которая всё сделает для нас сама.


cd
git clone git://repo.or.cz/fast-export.git
git init git_repo
cd ~/git_repo
~/fast-export/hg-fast-export.sh -r ~/mercurial-repo
git checkout HEAD

В итоге, в текущей папке мы получим самый настоящий git.


Шпион

Существует несколько способов сжечь книгу. И мир полон людей, бегущих с зажженными спичками.
«Звук бегущих ног», Рей Бредбери

Лирическое вступление

Наиболее устойчивые системы — децентрализованные и, к счастью, интернет из их числа. Своим появлением эта технология изменила всё. Никогда ранее не было возможно так просто обмениваться знаниями и новостями, иметь свободный доступ к практически любой точке земного шара. Это позволяет любому мнению быть услышанным — и это прекрасно и очень важно.

К сожалению, кроме людей созидающих знания, есть люди запрещающие знания. Запрещать знания — попросту глупо: знание есть знание, у него нет никакой моральной подоплеки, но оно, определенно, может быть кому-то не выгодно. И потому жгли людей, потом книги, теперь же они открыли для себя интернет. Но с интернетом такой фокус уже не пройдет. Потому что нам на помощь спешит VPN — виртуальные тоннели, с помощью которых мы будем выходить в интернет, например, из Амстердама, на самом же деле потягивая чаек из натурального русского самовара.


Docker

Что такое оркестрация?

Оркестрация — это координация взаимодействия нескольких контейнеров. В принципе, ничто не мешает создать контейнер, в котором запущены сразу все необходимые процессы, но этот подход лишен гибкости при масштабировании, изменении архитектуры, а также создает проблемы с безопасностью, т.к. в этом случае процессы никак не изолированы и могут без ограничений влиять друг на друга. Оркестрация же позволяет строить информационные системы из небольших кирпичиков-контейнеров, каждый из которых ответственен только за одну задачу, а общение осуществляется через сетевые порты и общие директории. При необходимости контейнеры в таком «оркестре» можно заменять на другие: например, чтобы проверить работу приложения на другой версии базы данных.


Docker

Containerization is the new virtualization
The Docker Book

Что такое Docker?

В отличии от классических систем виртуализации, которые эмулируют работу компьютерного железа и ядра операционной системы поверх него, Docker использует виртуализацию на уровне ядра: все виртуализируемые им процессы делят ядро операционной системы хоста, что позволяет значительно сократить как требуемые ресурсы, так и время, необходимое на запуск/обслуживание таких систем. В идеале, каждый процесс изолируется в собственном контейнере (linux container, lxc), который содержит набор необходимых ему библиотек, что позволяет забыть о dependecy hell, а также легко переносить стек проекта между серверами. В статье ниже я проиллюстрирую, как можно использовать Docker для настройки среды разработчика, повторяющей среду продакшена: предположим, что там используется Ubuntu LTS, PHP 5.4, Nginx.


Честно говоря, я тоже не знаю. Это был всего лишь термин, который мы начали использовать. Из-за немного необычной структуры файловой системы, при которой информация о доступе к файлам хранится в виде плоского (двумерного) массива на диске, отдельно от всей информации об иерархии каталогов, лучшее, что я могу предположить (для «и») - это «индекс». Таким образом, и-номер являлся индексом в этом массиве, и-нод - выбираемым элементом массива. (Приставка «и-» использовалась в первой версии руководства; со временем дефис перестали употреблять).
Деннис Ритчи

Я был очень удивлен, когда получил ошибку следующего содержания при попытке открытия сессии:


PHP Warning:  Unknown: open(/tmp/sess_e34ad6u6f51gum3htmqkd7ldn6, O_RDWR) failed: No space left on device (28)

Ведь при этом df -h показывал такую картину, что свободного пространства много:


df -h


Filesystem          1K-blocks     Used Available Use% Mounted on
/dev/sda2            19091584  3784332  14314332  21% /
udev                  8192628        8   8192620   1% /dev
tmpfs                 3280992      284   3280708   1% /run
none                     5120        4      5116   1% /run/lock
none                  8202472       92   8202380   1% /run/shm
/dev/mapper/vg0-var  47926152 24100456  21368096  54% /var

Оказалось, кончились файловые дескрипторы (inode), но в сообщении об ошибке этого не указывается. Проверить количество файловых дескрипторов в системе можно такой командой:


df -i

Имеет смысл отслеживать эту метрику, как и занятое на диске пространство.


When Cindy and I went to Australia, we spent some time in the rain forests on the Queensland coast. One of the natural wonders of this area are the huge strangler vines. They seed in the upper branches of a fig tree and gradually work their way down the tree until they root in the soil. Over many years they grow into fantastic and beautiful shapes, meanwhile strangling and killing the tree that was their host.
Martin Fowler, «Strangler application»

strangler vines

Однажды мне достался большой и запущенный веб-проект, обладающий, наверное, всеми ярко выраженными признаками и проблемами, что вообще свойственны наследуемым системам. Все компоненты системы были написаны таким образом, что дальнейшее их расширение, изменение и поддержка если и были вообще возможны, превращались в настоящий кошмар для разработчиков и тестировщиков. Даже основные модули, такие как ядро и маршрутизация, были тесно завязаны на серверное окружение, миллион магических цифр, динамически назначаемых констант, огромных ветвистых функций и неочевидных хаков. Цикломатическая сложность с тремя нулями не была чем-то удивительным.


Иногда требуется удалить множественные слеши из адреса, например:

http://mysite.com//page//1.htm/ -->http://mysite.com/page/1.htm

В этом случае, можно использовать следующую конструкцию для удаления слешей из середины:


set $test_uri $scheme://$host$request_uri;
if ($test_uri != $scheme://$host$uri$is_args$args) {
    rewrite ^ $scheme://$host$uri$is_args$args? permanent;
}

И с конца:


rewrite ^/(.*)/$ /$1 permanent;


2+2

Одной из самых плохо расширяемых частей любого веб-приложения является его клиентский код, как правило, написанный на javascript. Во многих проектах он представляет собой джунгли из функций, принимающих коллбеки — и это в лучшем случае. Многие склонны винить в таком положении дел непосредственно сам язык, припоминая его «низкое» происхождение, странное поведение и отсутствие синтаксического сахара. Несомненно, в этом есть своя правда. Но я полагаю, что основная причина такой запутанности заключается в том, что построить для взаимодействия с интерфейсом стройную и расширяемую архитектуру, руководствуясь только принципами императивного программирования — невозможно. И хотя модель реализации событий в браузере сама подводит к идее организации кода декларативно, почему-то немногие на это отваживаются.


Есть такой замечательный сервис Toggl, позволяющий отслеживать затраты времени между разными трекерами задач, или вовсе без оных. К сожалению, расширение для Google Chrome, добавляющее автоматические кнопки к задачам в трекере, работает не везде, где хотелось бы. Например, оно будет работать, если вы покупаете Jira в облаке (*.atlassian.net), но и усом не поведет, если у вас Jira на собственном сервере (jira.*.com). Ничего, выход есть — и довольно простой.


git clone https://github.com/toggl/toggl-button
cd toggl-button
nano src/manifest.json

Необходимо добавить строчки в permissions и content_scripts:


...
"permissions": [
    "tabs",
    ...
    "*://myawesomeredmine.com/*",
    "*://jira.myawesomesite.com/*"
  ],
...
"content_scripts": [
    {
      "matches": [
        ...
        "*://myawesomeredmine.com/*",
        "*://jira.myawesomesite.com/*"
      ],
      ...
     {
         "matches": ["*://myawesomeredmine.com/*"],
         "js": ["scripts/content/redmine.js"]
     },
     {
         "matches": ["*://jira.myawesomesite.com/*"],
         "js": ["scripts/content/jira.js"]
    }
  ]

Этого достаточно. Полученную версию можно установить прямо в распакованном виде (в режиме разработчика), либо запаковать и установить обычным способом.