пятница, 5 апреля 2019 г.

Установка OpenGrok на чистую Debian Linux


1. Сначала я установил debian. Сеть во время установки автоматически была сконфигурирована, так что после перезагрузки я вынужден был заново ее настроить

Файл /etc/network/interfaces

auto eth0
iface eth0 inet static
address 192.168.0.152
gateway 192.168.0.1
netmask 255.255.255.0

Кстати, в debian смотреть текущую конфигурацию сети нужно так:

ip a

2. Скачиваем свежие версии tomcat и opengrok:

wget -c http://apache-mirror.rbc.ru/pub/apache/tomcat/tomcat-8/v8.5.39/bin/apache-tomcat-8.5.39.tar.gz
wget -c https://github.com/oracle/opengrok/releases/download/1.2.5/opengrok-1.2.5.tar.gz

и распаковываем в /opt/tomcat-8 и в /opt/opengrok

3. Клонируем репозиторий ctags:

git clone https://github.com/universal-ctags/ctags

4. Устанавливаем средства для построения программы из исходников:

apt-get install make
apt-get install autoconf
apt-get install pkg-config
apt-get install gcc

5. Заходим в каталог проекта и даем последовательность команд:

./autogen.sh
./configure --prefix=/usr
make
make install

6.  Устанавливаем системные переменные в .profile (.bashrc)

export CATALINA_BASE=/opt/tomcat-8/
export CATALINA_HOME=/opt/tomcat-8/
export CATALINA_TMPDIR=/opt/tomcat-8/temp/
export OPENGROK_TOMCAT_BASE=$CATALINA_HOME
export OPENGROK_WAR_TARGET_TOMCAT=/opt/tomcat-8/webapps/

7. Копируем /opt/opengrok/lib/source.war в /opt/tomcat/webapp/source.war

8. Редактируем /opt/tomcat/webapp/source.war/WEB-INF/web.xml

Необходимо прописать путь к файлу конфигурации opengrok

9. В /opt/opengrok/src положим исходники для индексации

10. Запускаем индексирование:

java -Djava.util.logging.config.file 
=/opt/opengrok/logging.properties  
-jar /opt/opengrok/lib/opengrok.jar  
-c /usr/bin/ctags  
-s /opt/opengrok/src 
-d /opt/opengrok/data 
-H -P -S -G     
-W /opt/opengrok/etc/configuration.xml 
-U http://localhost:8080/source

11. Заходим на веб-сервер по адресу: http://имя_сервера:8080/source

Визуализация персептрона (искусственной нейронной сети)


Одной из важных задач при при оформлении материалов, посвященных ИНС (искусственным нейтронным сетям), является визуализация топологии сети. На сайте уважаемого Thiago G. Martins увидел рисунок, выполненный с помощью программы dot, входящей в пакет Graphviz

На этом рисунке имеется существенный дефект: концы стрелок, придающие рисунку отталкивающий вид. Исходный код рисунка может быть откорректирован, путем добавления опции [dir=none] после указания связи между нейронами двух слоев.


digraph G {
  rankdir=LR
  splines=line
        
  node [fixedsize=true, label=""];
  subgraph cluster_0 {
  color=white;
  node [style=solid,color=blue4, shape=circle];
  x1 x2 x3;
  label = "(Входной слой)";
 }

 subgraph cluster_1 {
  color=white;
  node [style=solid,color=red2, shape=circle];
  a12 a22 a32;
  label = "(Скрытый слой)";
 }

 subgraph cluster_2 {
  color=white;
  node [style=solid,color=seagreen2, shape=circle];
  O;
  label="(Выходной слой)";
 }

   x1 -> a12 [dir=none]
   x1 -> a22 [dir=none]
   x1 -> a32 [dir=none]
   x2 -> a12 [dir=none]
   x2 -> a22 [dir=none]
   x2 -> a32 [dir=none]
   x3 -> a12 [dir=none]
   x3 -> a22 [dir=none]
   x3 -> a32 [dir=none]

   a12 -> O [dir=none]
   a22 -> O [dir=none]
   a32 -> O [dir=none]

}

После составления кода можно сформировать рисунок в формате PNG командой:

dot -Tpng -O 1.txt

Результат:

среда, 3 апреля 2019 г.

Пример с использованием r-value ссылок в С++


Данный пример иллюстрирует проблему и ее решение.

Допустим, нам необходимо реализовать операции сложения и присваивания для некоторого объекта. Мы не можем использовать в качестве параметров ссылки на константу, поскольку при выполнении операций внутри каждого объекта меняет свое значение итератор. Операция сложения должна возвращать объект, созданный в стеке внутри функции. Но тогда на вход присваивания пойдет ссылка на временный объект, размещенный в стеке, что не разрешит использовать const Object& в качестве параметра присваивания. Выходом из ситуации является использование r-value ссылки.

#include <cstring>
#include <utility>
using namespace std;
const int size=10;
class Object
{
private:
  int data[size];
  int iter;     // моделируем использование итератора внутри объекта
public:
  Object(int val) :iter{ 0 } { 
    for (iter = 0; iter < size; ++iter)
      data[iter] = val;
    iter = 0;
  }
  // здесь приходится использовать ссылку на временный объект в стеке
  Object& operator=(Object&& obj) { 
    for (iter = 0, obj.iter = 0; iter < size; ++iter, ++obj.iter)
      data[iter] = obj.data[obj.iter];
    iter = 0;
    obj.iter = 0;
    return *this;
  }
  Object(Object& obj) {   // нельзя использовать ссылку на константу!
    for (iter = 0, obj.iter = 0; iter < size; ++iter, ++obj.iter)
      data[iter] = obj.data[obj.iter];
    iter = 0;
    obj.iter = 0;
  }
  Object operator+(Object& obj) {  // нельзя использовать ссылку на константу!
    Object result(0);
    for (iter = 0, obj.iter = 0; iter < size; ++iter, ++obj.iter)
      result.data[iter] = data[iter]+obj.data[obj.iter];
      iter = 0;
      obj.iter = 0;
      return result;  // возвращаем объект, копируя его через стек
  }
};

int main()
{
  Object a{ 1 }, b{ 2 }, c{ 0 };
  c = a + b;
  return 0;
}

понедельник, 25 сентября 2017 г.

Apple Time Machine и лечение при работе с сетевыми устройствами (продолжение)


Эта заметка является дополнением к предыдущей.

Пришлось снова и снова сталкиваться с ошибкой Time Machine:

Программа Time Machine завершила проверку резервных копий. Для повышения надежности программа Time Machine должна создать новую резервную копию

Несмотря на прилагаемые усилия, "починка" устройства с резервной копией не всегда завершалась успешно. Проблема обычно была в том, что монтируемая файловая система либо не могла быть изменена, либо ошибки оставались без исправления (fatal errors!)

Так продолжалось довольно долго, пока не встретилась в интернете эта статья.

Предлагается немного модифицированная последовательность команд (как всегда, подставляйте правильные имена для своих устройств, клавиша TAB для автодополнения в помощь!):

chflags -R nouchg /Volumes/TimeMachine/name.sparsebundle

hdiutil attach -nomount -readwrite -noverify -noautofsck /Volumes/TimeMachine/name.sparsebundle

В последней команде обратите внимание на параметр readwrite, он очень важен!

Далее, в предлагаемом списке выбираем нужное устройство:

/dev/disk2 GUID_partition_scheme /dev/disk2s1 EFI /dev/disk2s2 Apple_HFS


И вот, главное: используем вместо fsck_hfs программу diskutil:

diskutil repairVolume /dev/disk2s2

Проверка файловой системы сопровождается исправлением ошибок.

В завершении нужно открыть файл com.apple.TimeMachine.MachineID.plist
на устройстве внести в него исправления, которые описаны в предыдущей статье.

Успеха!

Выражаю искреннюю благодарность автору оригинальной заметки Tony Lawrence :-)

воскресенье, 17 января 2016 г.

Новый Gitlab и TeamCity


По адресу https://www.turnkeylinux.org/gitlab доступна новая, 14 версия дистрибутива Turnkey linux с установленным Gitlab 7 версии. Доступна она, правда, с сентября прошлого года, но только в начале 2016 года я до нее добрался, скачал работоспособный образ EXSI (.ova) и установил на свой HP N54L. Установка проходит обычным образом и не требует дополнительных манипуляций при условии, что мы соглашаемся со всем, что предлагает нам инсталлятор. 

Новая версия предлагает иную организацию главного окна, в которой панель управления располагается слева, как в Bitbucket:


В качестве пробы, я создал простой git-проект Hello, world! и загрузил его на сервер.

Следующим шагом захотелось развернуть сервер непрерывной интеграции (CI). Выбор пал на TeamCity, который был скачан и развернут на debian-системе. К достоинствам продукта можно отнести то, что после распаковки в произвольную директорию нужно запустить сервер командой из терминала, а после через браузер обратиться по адресу:  http://server_ip:8111 и сделать необходимые настройки.

Для проекта Hello, world! необходимо указать команду для построения проекта:

В результате, после внесения в проект изменений, TeamCity будет запрашивать исходный код из репозитория, строить с помощью gcc и выдавать код результата.

Разумеется, приведенный пример очень прост и требует расширения. Следующим этапом будет рассмотрение юнит-тестирования контроль за выполнением тестов со стороны приложения.




понедельник, 11 января 2016 г.

Манипуляции с DOSBox

Некоторое время назад я решил вспомнить, как играл в середине 90-х годов в сверхпопулярные тогда игры Civilization I, Dune II, а также Heroes of MM II и сыграть снова. Наиболее удобным способом запуска на Mac OS X вышеупомянутых игр является эмулятор DOSBox, который я без труда скачал и установил. Игры у меня хранились в домашнем каталоге, в подкаталоге dos. После запуска эмулятора необходимо смонтировать виртуальный диск C, на котором и должны находится используемые программы.
Монтирование производится внутри эмулятора командой (для моих каталогов):

mount c ~/dos

После монтирования перейдем на виртуальный диск:

C:

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

cd HEROES2
Heroes2.exe

Основная проблема, с которой пришлось столкнуться на мониторах с высоким разрешением - это небольшой размер окна эмулятора. На Mac OS X окно не растягивается по-умолчанию и выглядит уж больно маленьким. Существует возможность перехода в полноэкранный режим (CTRL+Enter), но теперь размеры изображения чересчур велики и могут показаться сильно искаженными. Нужно было найти другое решение.

В домашнем каталоге я создал текстовый файл dosbox.conf и поместил в него следующие настройки:

[sdl]
fullscreen=false
fullresolution=desktop
windowresolution=1280x1024
output=opengl

Принципиально важна в этих настройках последняя строка, в которой задается устройство вывода графики. Если установить его в opengl (а другие я не проверял), то появляется возможность масштабировать окно, задавая разрешение параметром windowresolution.

После всех настроек можно запустить DOSBox из терминала MAC OS X:

$ open -a DOSBox --args -conf ~/dosbox.conf

В результате я получил окно эмулятора с разрешением не 800x600 (SVGA) или даже 640x480 (стандартный VGA), а 1280x1024.

пятница, 4 сентября 2015 г.

Как я GitLab разворачивал...

Моим любимым севером для хранения Git-репозитариев является уже несколько лет bitbucket.org. GitHub тоже не плох, но в свое время меня подкупила возможность создавать закрытые хранилища на BitBucket и я остановился на нем. Тем не менее, возможность развернуть Git-сервер в локальной сети, продолжала интересовать и вчера было принято решение установить GitLab.

В качестве способа установки был выбран образ TurnKey Linux, позволяющий развернуть виртуальную систему на ESXI-сервере VMWare. Имея опыт работы с ESXI, совсем нетрудно выполнить эту задачу. Когда виртуальная система загрузится, то по протоколу DHCP ей будет присвоен IP-адрес (например, 192.168.0.154) и запустится процедура начальной настройки GitLab-приложения, созданного на платформе Ruby On Rails.

Следует отметить, что для комфортной работы нужно выставить в настройках образа виртуальной машины не менее 1ГБт оперативной памяти, так как платформа RoR весьма "прожорлива".

После несложной настройки в консоли, можно пробовать соединяться с приложением по сети. Я набрал в адресной строке браузера http://192.168.0.154. К сожалению, практически сразу вылезла ошибка сервера Nginx: 502 Bad gateway. Пришлось поколдовать, пользуясь советами, опубликованными на форумах: нужно соединиться с системой по SSH (или войти в консоли ESXI-сервера), перейти в каталог /home/git/gitlab и дать команду:

sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production

Также следует задать пароль пользователя Git:  $ sudo passwd git, иначе потом при соединении будут проблемы. Обязательно нужно протестировать SSH-соединение:  ssh git@192.168.0.154 
и, в случае необходимости, сгененрировать пару ключей для работы по протоколу.

После манипуляций удалось загрузить web-приложение и создать репозиторий на сервере, предварительно создав нового пользователя (с логином anton).

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

git remote add origin git@192.168.0.154:/repositories/anton/hello.git

а потом записать на него изменения:

git push -u origin master