Установка Virtualbox Guest additions в Ubuntu Server

Что за дополнения и для чего они нужны?

Virtualbox Guest additions изначально были сделаны для систем линейки Windows (согласно документации) и представляют из себя набор драйверов и утилит для управления гостевой ОС.

В Linux эти дополнения так же набор драйверов, но представляют собой модули для ядра. В связи с этим, модули необходимо пересобирать каждый раз, как будет обновлён пакет ядра Linux (linux-image-*), если в системе не установлен DKMS.

В большинстве *nix систем модули Virtualbox присутствуют, но зачастую очень старых версий. В официальной документации рекомендуется заменять их Дополнениями, актуальными для версии Virtualbox, установленной на хосте.

Устанавливаем

Итак, для того чтобы установить дополнения гостевой ОС, необходимо:
  • Обновить гостевую систему, так как модули ядра работают только с той версией ядра, на которой они собраны:
    sudo apt-get update && sudo apt-get upgrade

  • Установить build-essential, так как мы планируем собирать модуль ядра, а данный метапакет содержит необходимые нам make и gcc:
    sudo apt-get install build-essential

  • К счастью, в Ubuntu есть DKMS и нам не придётся собирать модули в ручную каждый раз, как обновили систему. Ставим его:
    sudo apt-get install dkms

  • В меню Virtualbox выбираем Устройства → Установить Дополнения гостевой ОС или нажимаем Host+D. Монтируем cdrom:
    sudo mount /dev/cdrom /media/cdrom

  • Переходим на смонтированный диск и запускаем установку:
    cd /media/cdrom && sudo sh ./VBoxLinuxAdditions.run
Дальше установщик сделает всё сам.
В случае, если вы проделываете это не в Ubuntu или в Ubuntu до 8.10, или в вашей системе попросту отсутствует DKMS, то необходимо будет после каждого обновления ядра системы пересобирать модули Virtualbox. Для этого необходимо выполнить команду sudo /etc/init.d/vboxadd setup.

Использование локального принтера в сеансе удалённого доступа — RDP printer redirection/mapping

Для того, чтобы использовать ваш локальный принтер необходимо проделать следующее:


  1. Разрешить подключение локальных принтеров в удалённом сеансе:


  2. После подключения необходимо установить драйвер принтера (такой же, как вы используете локально). На примере Samsung SCX-4216F:

    Скачать и установить

    Принтер скорее всего появится в списке. УДАЛЯЕМ ЕГО.

    Удостоверяемся, что необходимый драйвер остался задействован. Файл → Свойства сервера → Драйверы:

    Отключаемся от RDP и подключаемся снова — локальный принтер должен появиться при подключении

Use cases:


  • Терминальный сервер 1С: печать на принтер, который стоит рядом

  • Терминальный сервер «…»: печать на принтер, который стоит рядом


Восстановление писем из архива Kerio Mail/Connect — вытащить иголку из стога

В один прекрасный день, у одной прекрасной дамочки пропали письма в Outlook'е, да при этом аж за три месяца. Очень странным это может показаться, но .pst и не такое умеет.

В качестве сервера почты работает Kerio Connect 7.0.1 build 1249. Включены бэкапы, но работают они не так, как хотелось бы — делается копия текущего состояния ящика (а у пользователей, конечно же, стоит удаление писем с сервера).

К счастью, когда-то давно мной была выставлена спасительная галочка в настройках — «сохранять архив сообщений», благодаря которой Kerio любезно складывал всю почту (почта raw — там и спам, при желании можно заставить kerio и вирусы туда класть) за последние полгода в архив. Вздохнули с облегчением.

Структура архива Kerio Connect/Mail

А структуры нет. Ну, я конечно же преувеличиваю.. Но она ужасна.
Архив делится на папки по месяцам. И все, чёрт побери, все письма за этот месяц лежат в одной папке. В моём случае писем было ≈15 тысяч. Что может быть проще — разделить почту на папки на уровне почтового сервера, выделив почтовые адреса как сущности.

Разделить архив по получателям

Ну, это было первой идеей. Позже руки опустились, к сожалению. Поскольку писем много, а нам нужен только один получатель — пойдём «лоб в лоб»: возьмём плохой и ужасный php, чудесный и прекрасный Notepad++, такой розовый и блондинистый Denwer.. В общем, как обычно.

Спасительный говнокод.

  1. <?php
  2.    foreach( new DirectoryIterator( '.' ) as $file ) {
  3.       if ( $file->isDot() || $file->isDir() || $file->getFilename == __FILE__ ) {
  4.          continue;
  5.       }
  6.       
  7.       $name = $file->getFilename();
  8.       $file = file_get_contents( './' . $name );
  9.       if ( preg_match( '/(whatShouldWeFind@domain.(ru|com))/', $file ) ) {
  10.          rename( './' . $name, '../#saved/' . $name );
  11.          echo "moved " . $name . PHP_EOL;
  12.       }
  13.       
  14.       echo "skipped " . $name . PHP_EOL;
  15.    }
Ах да — мне было лень, создайте сами папку #saved рядом с #messages. Скрипт класть в папку #messages. Запускать как-то так: cd dirWithArchive/2011-Jan/#msgs && /usr/local/php5/php script.php. В 9-й строке меняется необходимый получатель.

Подведём итог

Скрипт ужасен. Скрипт работает. Разработчики Kerio в очередной раз доказали, что продукт хорош до тех пор, пока его используют стандартно — поставили, взломали через ukaip86.exe, настроили и забыли.
Спасибо за внимание.

reset.css — так ли всё хорошо?

Наткнулся на необычный и интересный баг — <b> и <strong> не делают текст полужирным, если использовать reset.css от Eric A. and Kathryn S. Meyer:

Решение: закомментировать 23-ю строку в reset.css (font: inherit;). Пользуйтесь.

Интересное поведение Google Chrome

Наткнулся на удивительное: мало того, что Chrome кастомизирует страницу с ошибкой, так ещё и докладывает, что я не один не могу открыть сайт. Приятно.

jQuery.mousewheel: обработка событий колеса мыши

В данной статье мы будем пользоваться jquery.mousewheel.

Для того, чтобы обработать событие скролла, необходимо повесить listener на определённый элемент:
  1. $('#wrapper')
  2.    .mousewheel(function (event, delta) {
  3.       //code
  4.    })
  5. ;
Пример — как обработать скролл — делаем горизонтальную прокрутку блока при вращении колёсика мыши:
  1. $('#photo-wrapper')
  2.    .data('scrollLeft', -1) //для предотвращения блокировки вертикального скролла
  3.    .mousewheel(function (event, delta) {
  4.       if ( (!this.scrollLeft && delta > 0) || (this.scrollLeft == $(this).data('scrollLeft') && delta < 0) ) {
  5.          return true; //данный блок необходим для того, чтобы перестать блокировать вертикальный скролл, если горизонтальный закончился
  6.       }
  7.       
  8.       $(this).data('scrollLeft', this.scrollLeft); //сохраняем текущий скролл слева
  9.       
  10.       this.scrollLeft -= (delta * 300); //на сколько прокрутить блок? (размер скролла)
  11.       return false; //отключить вертикальный
  12.    })
  13. ;

jQuery's .animate вешает chrome/webkit на ≈10 секунд (загрузка процессора 100%)

Есть в одном проекте следующий код:
  1. $(t)
  2.    .css({'border': '9px solid #D9D9D9'})
  3.    .animate({'border': '9px solid #C62417'}, 'fast')
  4.    .animate({'border': '9px solid #D9D9D9'}, 'fast')
  5.    .animate({'border': '9px solid #C62417'}, 'fast')
  6.    .animate({'border': '9px solid #D9D9D9'}, 'fast')
  7. ;
И вешает он браузер (Google Chrome 11.0.696.28 beta) при вызове события.
В чём же проблема? Как выяснилось, проблема в том, что создаются несколько одинаковых анимаций последовательно.

Решение — заменить одинаковые цвета на практически не отличающиеся, но немного другие:
  1. $(t)
  2.    .css({'border': '9px solid #D9D9D9'})
  3.    .animate({'border': '9px solid #C62417'}, 'fast')
  4.    .animate({'border': '9px solid #D9D9D8'}, 'fast')
  5.    .animate({'border': '9px solid #C62418'}, 'fast')
  6.    .animate({'border': '9px solid #D9D9D9'}, 'fast')
  7. ;
Таким образом анимации становятся разными и проходят с загрузкой процессора ≈1%.