28 октября 2012 г.

Object oriented Lazy GTK Cat

Загрузил в репозиторий LazyCat на GitHub последние изменения, являющиеся результатом почти месяца работы. Суть изменений заключается в том, что Lazy GTK Cat (текущий и пока единственный GUI для LazyCat) переведён на объектно-ориентированную модель.

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

Поскольку решаемая мной задача (GUI и некоторая высокоуровневая логика) хорошо поддаётся на разбиение на ясно определённые объекты, перевод на объектно-ориентированную модель позволил упростить код, сделать его ясным и удобным для понимания. А значит, дальнейшее добавление необходимых возможностей в GUI будет проще.

Я изучаю Scheme и GNU Guile по ходу работы над проектом и по мере решения возникающих проблем. И в этот раз много времени ушло на чтение документации и эксперименты с GNU Guile -- чтобы понять, как же реализовать объекты в языке. Сначала попробовал создавать объекты с помощью closures -- механизм, который "из коробки" присутствует в Scheme.

Вариант с closures оказался простым и достаточно удобным. Но я на этом не остановился и решил попробовать сделать то же самое с использованием Guile Object Oriented Programming System (GOOPS) -- модуля, который приносит объектно-ориентированность в язык. После того, как переписал готовые объекты с использованием GOOPS, я продолжил разделение того большого куска кода, которым являлся Lazy GTK Cat, на небольшие и относительно простые объекты. Стало ясно, что GOOPS является более мощным и удобным механизмом для создания объектов в языке.

Работу методов для некоторых объектов я проверил по отдельности, через написание скриптов на GNU Guile (одна из возможностей этого интерпретатора -- использование вместо shell-интерпретатора для написания скриптов на Scheme, которые можно выполнить прямо из консоли). После тестирования нужно было собрать всё воедино и заставить работать. Далее -- тестирование Lazy GTK Cat и дописывание оставшихся частей основного класса приложения. Всё это было сделано за несколько дней.

В коде много комментариев, в том числе, в последнем коммите я добавил "TODO" заметки -- напоминания, подсказки и идеи, как можно улучшить тот или иной кусок кода, что неплохо бы сделать в дальнейшем.

Я по-прежнему ищу разработчиков для проекта. Важна не только помощь, но и интересен опыт совместной работы над проектом через GitHub. Если вам интересен проект -- go ahead, буду рад помощи.

- Артём

14 октября 2012 г.

cowsay for Android

Сегодня к своему удивлению обнаружил в репозитории F-Droid порт Unix-утилиты cowsay для Android. Разумеется, я тут же установил такую полезную утилиту на свой коммуникатор:

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

Кроме коровы доступно множество других персонажей, так же можно менять отображение сообщения и некоторые параметры персонажа. Рекомендую вам установить эту утилиту в вашем дистрибутиве GNU/Linux (если вы ещё не сделали этого) и поэкспериментировать с ней.

Как и большинство утилит Unix, cowsay может быть использована в конвейере команд. Кроме того, существует вариант утилиты cowthink, который отличается тем, что выводит сообщение в "облаке мыслей":

$ cat hello.c | cowthink -W 80 -n
 _______________________________________________ 
( #include <stdio.h>                            )
( #include <string.h>                           )
( #define S "Hello, World\n"                    )
( main(){exit(printf(S) == strlen(S) ? 0 : 1);} )
 ----------------------------------------------- 
        o   ^__^
         o  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

27 сентября 2012 г.

Проект LazyCat

Есть один проект, над которым я работаю уже достаточно давно. Проект называется LazyCat. Моей целью в рамках этого проекта является создание системы для администрирования множества (множества в математическом и в обычном смысле) компьютеров, объединённых в сеть.

Идея, которая стоит за данным проектом достаточно проста - если у вас есть много компьютеров, то иногда возникает потребность выполнить какие-то однотипные действия на всех ваших ПК. Или же бывает полезно получить "общую картину" происходящего. Это достаточно просто, когда у вас есть доступ к компьютерам (физический и/или сетевой), и когда компьютеров не много. С ростом количества компьютеров такая задача, как развёртывание программного дистрибутива, становится нетривиальной.

Возьмём наглядный пример.

Университет. Пятница. Вечер. Системный администратор по имени Боб допивает свой кофе и готовится уйти домой. И в тот момент, когда он уже накинул сумку на плечо и собрался уходить, к нему прибегает преподаватель и просит сегодня же установить на все компьютеры в классе номер 21 пакеты Inkscape и Gimp, так как только что стало известно, что в субботу будут проходить курсы по компьютерной графике.

Предположим, в классе 30 компьютеров. На каждый нужно установить необходимые программы и (возможно) произвести некоторую настройку - например, добавить учётные записи для новых пользователей. Итого - требуется выполнить порядка 60 одинаковых действий. Что в такой ситуации может сделать Боб? Он может, во-первых, пойти в класс номер 21 и поставить программы на каждый компьютер в отдельности. Но, поскольку за плечами Боба - годы системного администрирования, то он знает пару полезных трюков. Например, он может со своей машины зайти по SSH на каждый из компьютеров и выполнить установку. Но ему по-прежнему нужно залогиниться на каждый компьютер, выполнить установку и настройку вручную. Лучше, чем бегать от компьютера к компьютеру, но всё ещё не слишком удобно.

Было бы гораздо удобнее, если бы Боб мог отправить команду установки сразу всем компьютерам в классе 21, и получить обратно отчёт, если что-то пошло не так - например, если пакет уже был установлен в системе, или же во время установки произошла ошибка.

Есть достаточно большое количество программного обеспечения, которое решает подобную задачу (в Википедии есть обширный список) - например, Ansible и Puppet.

LazyCat - один из таких инструментов. Он написан на языке C и на Scheme (диалекте Lisp) с использованием Guile. На языке C написано ядро проекта и прокси-сервисы. Под прокси в данном контексте я понимаю процессы, которые непосредственно пересылают сообщение по сети конечному хосту. Графический интерфейс пользователя и высокоуровневая логика написаны на Scheme.

По сути, базовая часть LazyCat является интерпретатором Scheme с дополнительным API. Благодаря использованию Scheme, LazyCat можно легко расширить - например, написать другой интерфейс, добавить функциональность или же использовать его в автоматическом режиме.

Проект находится в разработке и пока не может похвастать большим количеством возможностей. Вот, что сделано на данный момент:

  • Графический интерфейс пользователя на GTK.
  • Выполнение команд на хостах через TCP- и SSH-подключения.
  • Базовый режим "Raw", в котором lazycat отправляет команду на все хосты из списка и отображает необработанный вывод команд.
  • Режим "Diff", при котором результат выполнения команды с каждого хоста сравнивается с результатом выполнения этой же команды с эталонного хоста.
  • Группировка хостов в списке (пока имеет чисто эстетический характер).
  • Сохранение и восстановление списка хостов между сессиями.

В ближайших планах:

  • Отладка.
  • Возможность выбора эталонного хоста перед отправкой команды в Diff-режиме (сейчас выбирается первый хост из списка).
  • Возможность изменять информацию о хосте из графического интерфейса (пока реализовано только API для этого).
  • Возможность отправки сообщений только выбранным хостам из списка, или же группе хостов.
  • Организация списка хостов по типу контакт-листа IM-клиента (за образец думаю взять Pidgin) - статусы, состояния (online/offline) и т.п.
  • Периодический опрос состояния хостов (для отображения их статусов в списке).

Сейчас над проектом работаю я один, just for fun, в свободное от работы время. В связи с этим прогресс идёт достаточно медленно, и проекту не хватает тестирования. Если вас заинтересовал LazyCat и вы можете и хотите поучаствовать в разработке - то вот страница проекта на GitHub, откуда вы можете получить исходный код (под GPLv3) и дополнительную информацию о проекте:

https://github.com/artyom-poptsov/lazycat

- Артём

20 сентября 2012 г.

Сентябрьский месяц над городом N^2

Осенний вечер, сентябрьское небо
Темнеет быстро - вот зажглись огни,
Весь горизонт теперь мерцает светом,
Лишь месяц отрешённо смотрит с высоты.

18 сентября 2012 г.

История Computer Science: Системы с разделением времени

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

http://hackaday.com/2012/09/17/retrotectacular-time-sharing/

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

Если не вдаваться в детали, то такая система выделяет каждой работающей программе кванты процессорного времени, и по прошествии каждого кванта управление передаётся обратно планировщику, который вибирает следующий процесс на выполнение. Если программа не занимается вычислениями (например, ждёт ввода команды от пользователя), то она может добровольно передать управление обратно планировщику до истечения выданного ей кванта времени. Таким образом, каждый пользователь системы может работать на машине одновременно с другими пользователями, в интерактивном режиме.

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

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

Во-первых, ей нужно подготовить для ЭВМ задание, записанное на магнитной ленте или на перфокартах. После этого она должна загрузить это задание в компьютер. В те времена пользователи часто не имели непосредственного доступа к ЭВМ, так что Алисе, скорее всего, нужно будет отдать её задание программисту по имени Боб (одному из обслуживающего персонала ЭВМ), который поместит задание Алисы в очередь на выполнение.

Теперь Алисе нужно ждать, пока задание будет выполнено (возможно, это займёт пару часов, если на ЭВМ много других заданий). Когда задание будет выполнено, Боб отдаст Алисе распечатку с результатами вычислений. Или же распечатку с программной ошибкой (если что-то пошло не так). Если в программе обнаружилась ошибка, то Алисе нужно будет внести необходимые изменения, создать новое задание, отдать его на выполнение и т.п.

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

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

Правда здорово?

- Артём

10 сентября 2012 г.

X-сервер в Debian GNU/Hurd и особенности системы

В комметарии к скриншоту из этого [1] поста мне задали два вопроса касательно текущего статуса GNU Hurd. Я решил опубликовать ответ здесь, так как он получился достаточно длинным и он может быть интересен ещё кому-нибудь (кого волнуют эти же вопросы).

Итак, вопрос первый:

> А X сервер на нем заводится?

На сайте Debian GNU/Hurd есть инструкция по запуску X-сервера [2] - судя по всему, сервер должен запускаться без особых проблем. У меня пока не получилось его запустить. Надо будет ещё раз попробовать - возможно, я что-нибудь упустил из виду при настройке.

В качестве подтверждения, что X-сервер действительно работает - вот обсуждение [3] Debian GNU/Hurd, где можно найти скриншоты иксов, работающих на Hurd, запущенном в QEMU.

> Ощущаются ли особенности архитектуры?

Во-первых, надо сказать, что система работает достаточно стабильно (по сравнению с тем, что я видел в Arch Hurd в начале года). Например, исправлена досадная ошибка с "замораживанием" консоли при простое системы (патч оказался достаточно тривиальным [4]).

Однако, в плане производительности Hurd всё ещё отстаёт от Linux - по собственным ощущениям, по крайней мере. При работе с разделами ext2 очень активно нагружает процессор ext2fs сервер (транслятор, в терминологии Hurd), который обеспечивает доступ к разделам с этой ФС - скажем, при aptitude upgrade он ест иногда более 40% CPU.

Вот скриншот с рабочей системы, на котором видно, что ext2fs заметно нагружает CPU (htop запущен через SSH-подключение):

Что интересно, по сути ext2fs представляет собой переписанный драйвер ext2 из Linux (насколько я понимаю), который отражает особенности Hurd - например, его i-node хранят так же информацию о трансляторах, которые являются частью Hurd. В системе даже привычный mount является ни чем иным, как скриптом, который запускает соответствующий транслятор для обслуживания запросов к монтируемому разделу.

Так что ты можешь видеть в ps/top/htop, что творится "под капотом" ОС - работу серверов, которые по сути и превращают микроядро Mach в Hurd.

На тему данную тему есть интересный обзор GNU Hurd с оценкой производительности, который был опубликован в прошлом году на Phoronix [5].

Ссылки: