Страницы

понедельник, 12 ноября 2012 г.

Haskell и XMonad в Ubuntu

Установка Haskell и XMonad в Ubuntu 12.10 Quntal Quetzal

Я заметил, что последнее время, с переходом на Gnome Shell, всё чаще использую полноэкранные режимы приложений на нескольких рабочих столах.
Стало несколько неудобно, каждый раз запускать и перемещать несколько приложений по различным столам, после перезагрузки.
Легкого решения для Gnome Shell не нашлось. А всего лишь надо, автозагрузка, авторасположение по рабочим столам, удобное расположение на столе и чтобы после перезагрузки ничего не менялось.

И вот, я докатился до Xmonad.


Фреймовый оконный менеджер Xmonad написан на языке Haskell и на нём же настраивается (буквально в файле ~/.xmonad/xmonad.hs).
Что может быть получено на экране с Xmonad [см. Ресурсы п.8]



Т.к. без обзорного знания языка Haskell не обойтись, то установим и сам язык Haskell, точнее его платформу Glasgow Haskell Platform [см. Ресурсы п.1].


Установка версии языка из репозитория Ubuntu:

$ sudo apt-get install haskell-platform haskell-platform-doc haskell-platform-prof

Установка версии xmonad из репозитория Ubuntu:

$ sudo apt-get install xmonad
После установки надо выйти из системы и войти, но уже со съянсом xmonad.
Появиться просто рабочий стол, без всего. Чтобы запустить bash окно, надо нажать Alt+Shift+Enter.



Запуск интерактивной среды языка Haskell:
$ ghci

Я, было в начале набрал haskell.:-)

Версия платформы:
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 7.4.2

Приглашение к вводу языковых конструкций и команд.
Prelude>



Prelude - это стандартная библиотека, загруженная по умолчанию, в каждой haskell-программе.

:quit - покинуть это "мутное" место
:help - справка по командам. "продолжить мутить"

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

Prelude> cos pi
Prelude> 2 ^ 2
Prelude> sqrt 4


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

Современные языки - модульные, поэтому библиотека Haskell разбита на модули и иерархична.
В Haskell есть репозиторий "open-source" программ - Hackage.

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


XMonad



Главный конфигурационный файл: ~/.xmonad/xmonad.hs

Синтаксис конфигурационного файла: язык Haskell.
По умолчанию, отсутствует. Для настройки - надо создать, либо взять готовый [см. Ресурсы п.8, п.12].

Базовые понятия:

Screen - монитор, в многомониторных конфигурациях
Workspace - аналогично Virtual Desktop Workspace, в X Window
Layout - расположение окон отображаемое на конкретном Workspace.
Master pane - главное окно, обычно самое большое в Layout.
Tile pane - остальные окна в Layout.


Минимальное содержимое конфигурационного файла ~/.xmonad/xmonad.hs:

import xmonad

main = do             xmonad $ defaultConfig

В Ubuntu, xmonad устанавливается как дополнительная сессия, так что её можно выбрать в окне входа в систему (GDM, LightDM).

И после появления пустого стола, сразу же создать окно (alt+shuft+enter) или несколько.
И сразу же завершить сессию (alt+shift+q), т.к. подготовиться лучше из привычного окружения.

Кобминации клавиш Xmonad, используемых по-умолчанию, можно найти здесь: http://www.haskell.org/haskellwiki/Image:Xmbindings.png



XMonad - в принципе, это подмножество библиотеки.

Для подключения модуля в файле функций (.hs) используется синтаксис:
import <имя модуля>

import xmonad - подключаем основные функции XMonad.

Далее мы определяем функцию с именем main (без параметров). Символ "=" - определение функции. Имя main - специальное имя - точки входа в программу на языке Hashell.

Тело функции, в данном определении, начинается со слова do - ключевое слово языка, объединяющего вызовы функций в порядок исполнения.

В Haskell используется отбивка (т.н. двумерный синтаксис, как в языке python), поэтому строка xmonad $ defaultConfig располагается после табуляции, т.е. отступы помогаю анализатору определить границы определений.

xmonad - это, понятно, вызов функции.
defaultConfig - это что-то большое, емкое, там есть что посмотреть - настроить. Т.к. Haskell функциональный язык, предположим, что это функция, переданная в качестве параметра. Из названия понятно, что это конфигурация по умолчанию. Больше ничего не понятно.:-)
$ - оператор нестрогого применения - это уже из учебника. Можно временно рассматривать как разделитель вызовов функций.

Далее, надо узнать что ещё есть внутри модуля xmonad, для этого посмотрим документацию [см. Ресурсы].
Откуда становиться понятно, что defaultConfig - это структура данных, с типом XConfig. Что нивелирует первоначальное предположение. А просмотр XConfig показывает т.н. конструкторы, которые можно использовать для конструирования уже нашей структуры данных, с нашими значениями, которые настроят нам Xmonad.

Вызовы конструкторов оформляются следующим образом:
{
имя конструктора = значения конструктора
}

Приведу некоторые из конструкторов здесь:
workspaces - как ясно из названия, конструктор задающий "виртуальные столы". Тип - список. Список имен виртуальных столов, в виде пар номер:название
keys - привязка клавиш к действиям.
mouseBindings - привязка кнопок мыши к действиям. Выражено как тип "map".

Есть несколько конструкторов, со словом hook в  названии и параметром в виде функции. Обычно они используются для вызова пользовательских функций, переопределенных в конфигурационном файле.

startupHook - выполняется при загрузке. Автозапуск.

manageHook - выполняется при создании (открытии) нового окна.
layoutHook - задает расположение окон тип Window.

terminal - указывается терминальная программа. Тип - строка.

Несколько конструкторов, относящихся к рамках окон.

normalBorderColor - цвет рамки обычного окна
focusedBorderColor - цвет рамки окна с фокусом ввода.

borderWidth - ширина рамки окон, Тип. Dimension


Теперь, самое время отвлечься и продумать структуру "виртуальных столов". Опыт уже имеется, при настройке tmux, так что это быстро.
Общий стол - для обычных задач, 3 или 4 окна, одно центральное, большое, одно с суперпользователем.
Интернет - 1 окно браузера, по возможности на весь экран.
Почта и связь - 2 -3  окна, почтовая программа, мессенджер.
Сервер - 1 окно. Сессия ssh к микросерверу.
Сеть - несколько окон, мониторинг домашней сети.
База - 1 окно с tmux, или несколько, с сессиями к базе данных PostgreSQL.
Просмотр - просмотр файлов на полный экран, либо 2 окна.
Фото - фотоальбом.
Видео - видеопросмотр.

9 - столов, 9 клавиш (mod+цифра).

Xmonad поддерживает многомониторные конфигурации,  с помощью средства Xinerama оконной системы X Window.

1 физический монитор (screen) - несколько рабочих столов (workspaces)
1 рабочий стол - несколько расположений (раскладок, layouts)
1 расположение - несколько окон

Т.е. при серьезной настройке можно получить "центр управления полетами в сети".

В принципе, раскладку окон можно задать и  в обычном файле xinitrc чистого X Window, если нужно постоянное неизменяемое расположение, раз и навсегда. Xmonad просто делает процесс попроще, чем опция --geometry.

Т.к. Haskell современный язык, то поддержка UTF-8 встроена по-умолчанию, а это, даёт нам некоторые приятные возможности, по повышению понимания конфигурации.



Например, зададим список рабочих столов на языке Haskell: (выдержка из моего xmonad.hs)


 стол_общий     = "1:Общий"     -- Общий рабочий стол
 общий_стол     = стол_общий    -- в другой языковой форме
 стол_интернет  = "2:Интернет"  -- Просмотр Интернета
 стол_почты     = "3:почта"     -- Почтовое и разговорное
 стол_сервер    = "4:Микросервер"  -- Доступ к серверу
 стол_сеть      = "5:Сеть"      -- Домашняя сеть
 стол_база      = "6:База"      -- База данных, разработка
 стол_просмотра = "7:Просмотр"  -- Справочные материалы
 стол_фото      = "8:Фото"      -- Фото
 стол_разное    = "9:разное"    -- Разговоры, файловый менеджер

 рабочие_столы  = [стол_общий,
                  стол_интернет,
                  стол_почты,
                  стол_сервер,
                  стол_сеть,
                  стол_база,
                  стол_просмотра,
                  стол_фото,
                  стол_разное
                 ]

Приятно то, что это легитимные определения в языке Haskell. Я не удержался, написал на русском языке почти всё, до чего дотянулся. Кстати, это действительно, резко повысило скорость восприятия конфигурации и скорость переконфигурирования, в моём случае.


Layout. Расположения. Расположение окон

Расположение (Layout).
В Xmonad стандартно поставляются 3 расположения.
Tall разделение по вертикали на главную и вспомогательную части
Mirror Tall - раделение по горизонтали на главную и вспомогательную части. Mirror - это модификатор.
Full -полноэкранное расположение, переключение между окнами mod+tab

Принцип, по которому устроены расположения, декораторы - это наслаивание (модифицирование), задается в виде: Модфикатор $ расположение. Например, Mirror - это модификатор, Tall - расположение,
master delta ratio - это параметры расположения Tall.
Еще пример, простой модификатор "spacing 5", модифицирует расположение, добавляя 5 пиксельный разрыв между окнами. Для него не важно какое расположение.
onWorkspace - это из модуля PerWorkspace (по столам) - позволяет задать для каждого стола свое расположение окон.
||| - оператор "выбора", насколько я понял.

 расположение =
   onWorkspace стол_разное ( общее_расположение ||| сеточное_расположение ) $
   onWorkspace общий_стол общее_расположение $
   onWorkspace стол_просмотра общее_расположение $
   onWorkspace стол_фото расположение_для_gimp $
   onWorkspaces [стол_интернет, стол_сервер] расположение_на_весь_экран $
   общее_расположение ||| общее_горизонтальное_расположение ||| расположение_на_весь_экран $
  where
   общее_расположение = spacing 5 $ Tall master delta ratio
   общее_горизонтальное_расположение = spacing 5 $ Mirror $ Tall master delta ratio
   defaultTall = ResizableTall 1 (3/100) (1/2) []
   master = 1
   ratio = 2/3
   delta = 3/100
   расположение_на_весь_экран = smartBorders $ Full
   сеточное_расположение = spacing 6 $ Grid
   расположение_для_gimp = simpleDeco shrinkText цветовое_оформление $ defaultTall


Здесь важное слово "where", которое позволяет определить функции и значения, после упоминания, что повышает восприимчивость синтаксиса.
Т.е. в этом блоке определения, я задаю конкретные расположения окон (layouts),  а выше, раскладываю их по рабочим столам.

Полноэкранное расположение Full

При полноэкранном расположении, каждое окно, занимает весь экран. Невозможно сдвинуть, изменить, скрыть. Зато возможно переключаться окнами в полноэкранном режиме, с помощью клавиатурных сочетаний mod + tab, где mod - по умолчанию alt, а у меня win.


Собственные привязки клавиш

Привязка определенной клавиши задается в виде пары - клавиша-действие. Затем все привязки помещаются в список и список передается в функцию.

На мультимедийной клавиатуре, часто присутствуют клавиши управлению громкостью звука, имена кодов XSymbols для этих кнопок, в Haskell определены так:

xF86XK_AudioLowerVolume
xF86XK_AudioRaiseVolume

xF86XK_AudioMute

Это мультимедийные клавиши, поэтому без модификатора.
Мы их можем задать в виде именованного списка:

 мультимедийные_клавиши = [
          ((0, xF86XK_AudioLowerVolume), kill)          -- уменьшает громкость
        , ((0, xF86XK_AudioRaiseVolume), kill)          -- увеличивает громкость
        , ((0, xF86XK_AudioMute), kill)                 -- выключает звук
        ]

Здесь, они временно выполняют функцию "kill" - закрыть окно. Т.к. с управлением звуком из XMonad я еще не определился. В Gnome присутствует PulseAudio, а это надо RTFM.

Потом, просто соединим этот список клавиш и основной. Т.е. мы логически сгруппируем привязку клавиш, для удобства просмотра и изменения.


Часто встречаются клавиши:

xF86XK_HomePage
xF86XK_Mail
xF86XK_Files
xF86XK_Favorites

По аналогии, также сформируем список дополнительных клавиш, присутствующих на клавиатуре.

  клавиши_запуска = [
          ((0, xF86XK_Close), kill)                     -- Закрыть окно
        , ((0, xF86XK_HomePage), spawn "firefox http://gimmor.blogspot.com/")
        , ((0, xF86XK_Mail), spawn "evolution")         -- Почта
        , ((0, xF86XK_Calculator), spawn "gcalctool")   -- Калькулятор
        , ((0, xF86XK_LogOff), spawn "gcalctool")       -- Выйти из съянса

        , ((0, xF86XK_Sleep), spawn "gcalctool")        -- Спящий режим
        , ((0, xF86XK_Launch1), spawn "gcalctool")      -- Проверка
        , ((0, xF86XK_Favorites), spawn "nautilus")     -- Файлы
        , ((0, xF86XK_Messenger), spawn "skype")        -- Разговоры
        ]

spawn - это команда запуска внешнего приложения
gcaltool - калькулятор, для клавиш, которые ещё не настроены.


Поработаем над секцией import

import Graphics.X11.ExtraTypes.XF86 - содержит определения клавиш,таких как мультимедия клавиши.
Полные определения можно найти в файлах: Graphics/X11/Types.hsc и Graphics.X11.ExtraTypes.hsc.

import XMonad.Layout.Spacing - позволяет раздвинуть окна, для лучшего визуального выделения.

import XMonad.Layout.NoBorders(smartBorders) - позволяет показывать окна без рамок

import XMonad.Layout.PerWorkspace - позволяет задавать конфигурацию для каждого рабочего стола

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


ManageHook. Заглушки поведения

Заглушки поведения, это "подпрограммы", которые вызываются менеджером Xmonad, при создании нового окна. Новое окно, в X Window имеет некоторые свойства, на основе которых Xmonad может принимать решения, относительно того, что делать с этим окном. Будь то, переместить на другой рабочий стол, разместить по центру и многое другое.

Значимые свойства окна в X Window, пример:

WM_CLASS: className =? "Firefox"
WM_TITLE: title =? "Firefox"
WM_NAME: appName =? "firefox"
WM_ROLE: (getStringProperty "WM_ROLE") =? "Roster window"

Вот выдержка того, как я задаю поведение:

 поведение_программ = composeAll
      [ поведение_браузеров
      , поведение_просмотрщиков
      , поведение_почтовых
      , для_калькулятора
      , для_скайпа
      , для_файлового_менеджера
      , для_менеджера_фотографий
      , для_minitube
      , для_gimp
      , className =? "File Operation Progress" --> разместить_по_центру_стола
      , поведение_диалоговых_окон
      ]

Здесь я также, разложил на маленькие кусочки кода, для лучшего понимания. Чуть ниже идут определения, уже конкретные:

        isDialog --> разместить_по_центру_стола

 поведение_браузеров =
        className =? "Firefox"
        --> doShift стол_интернет

В этих определениях, уже вызываются функции специфичные для Xmonad, выполняющие определенные действия (например, doShift - переместить на указанный стол). Здесь решение выполняется на основе класса окна (className).

Конфигурация и её вызов

Полная конфигурация, задается на основе встроенной конфигурации по-умолчанию, путем модификации вызовов функций, посредством конструкторов.
Здесь я меняю клавишу mod, с alt, на win. Указываю свой список рабочих столов, добавляю свои привязки клавиш и мыши, указываю заглушки поведения и свои расположения.

 рабочая_конфигурация = defaultConfig
     { manageHook = manageDocks
        <+> поведение_программ
                 <+> manageHook defaultConfig
     , layoutHook = avoidStruts $ расположение
     , terminal = "gnome-terminal --hide-menubar"
     , modMask = mod4Mask  -- меняем привязку клавиши, вместо alt будет  win
     , workspaces = рабочие_столы
     , normalBorderColor = цвет_рамки_обычного_окна
     , focusedBorderColor = цвет_рамки_выделенного_окна
     , borderWidth = 4
     , startupHook = return ()
     }  `additionalKeys` все_клавиши
        `removeKeys` удаляемые_клавиши
    -- `additionalMouseBindings` клавиши_мыши


Вызов конфигурации происходит в главной фукнции main так:

 main = do
   xmonad $ рабочая_конфигурация


Т.е. прослеживается путь от точки входа, к каждой секции конфигурации.


Общая сборка конфигурационного файла Xmonad


Приведу файл настроек Xmonad, таким, как он находится на текущий момент конфигурации. Пошёл 3 день общения. Пока не подключен xmobar.



После копирования файла в папку .xmonad/ запустить компиляцию:

$ xmonad --recompile

Файл у меня компилируется нормально, проблемы очень часто возникают из-за отступов и из-за пропуска подчеркивания в русских именах. :-)

$ cat $HOME/.xmonad/xmonad.hs

 -- Конфигурация xmonad для рабочего стола X Window
 -- сервер: mir
 -- Система: Ubuntu 12.10 Gnome Shell,X Window, xmonad, xmobar
 -- Дата основания: 10.11.2012
 -- Описание в web: http://gimmor.blogspot.com/label/xmonad
 -- Ключевые слова: xmonad, xmonad.hs

 -- Содержание
 --
 --    I. Секция импорта библиотек
 --   II. Секция имен рабочих виртуальных столов (пространств)
 --  III. Секция расположений для рабочих виртуальных столов
 --   IV. Секция заглушек поведения специфических приложений
 --    V. Секция офрмления (цвета, шрифты)
 --   VI. Секция привязки клавиш
 --  VII. Секция привязки мыши
 -- VIII. Секция автозагрузки внешних программ
 --   IX. Секция конфигураций
 --    X. Секция главной функции main - точка входа
 --     . Дополнительная информация
 --     . Ресурсы


 ----------------------------------------------------------------------------------------
 --    I. Секция импорта библиотек (подключение пространств иимен)
 ----------------------------------------------------------------------------------------

 import XMonad
 import XMonad.Hooks.DynamicLog 
 import XMonad.Hooks.ManageDocks        -- Управляет выделением места на экране
 import XMonad.Hooks.ManageHelpers        -- Вспомогательные функции размещения
 import XMonad.Util.Run (spawnPipe)          -- Утилита для запуска внешних программ
 import XMonad.Util.EZConfig 
 import Graphics.X11.ExtraTypes.XF86          -- Определения мультимедийных клавиш в X

 import XMonad.Layout.Spacing              -- Визуальные разрывы между окнами
 import XMonad.Layout.NoBorders(smartBorders)   -- Окна без рамок
 import XMonad.Layout.PerWorkspace          -- Разные расположения для столов
 import XMonad.Layout.ResizableTile        -- изменение размеров
 import XMonad.Layout.IM              -- Расположение для мессенджеров
 import XMonad.Layout.Grid            -- Расположение - сетка окон 
 import XMonad.Layout.SimpleDecoration        -- Простой декор вокруг окна
 import XMonad.Layout.BorderResize

 --import XMonad.Actions.GridSelect
 import Data.Ratio ((%)) 
 import XMonad.Actions.CycleWS            -- Циклическое переключение столов 
 import qualified XMonad.StackSet as W 
 import System.IO 
 import XMonad.Util.Font

 ----------------------------------------------------------------------------------------
 --   II.  Секция задания имен рабочих виртуальных столов (всего 9)
 ----------------------------------------------------------------------------------------

 стол_общий     = "1:Общий"       -- Общий рабочий стол
 общий_стол    = стол_общий    -- ссылка, в другой языковой форме
 стол_интернет  = "2:Интернет"     -- Просмотр Интернета
 стол_почты     = "3:почта"        -- Почтовое и разговорное
 стол_сервер    = "4:Микросервер"  -- Доступ к серверу
 стол_сеть      = "5:Сеть"      -- Домашняя сеть
 стол_база      = "6:База"         -- База данных, разработка
 стол_просмотра = "7:Просмотр"     -- Справочные материалы
 стол_фото      = "8:Фото"        -- Фото
 стол_разное    = "9:разное"       -- Разговоры, файловый менеджер

 рабочие_столы  = [стол_общий,
          стол_интернет,
          стол_почты,
          стол_сервер,
          стол_сеть,
          стол_база,
          стол_просмотра,
          стол_фото,
          стол_разное
         ]


 ----------------------------------------------------------------------------------------
 --  III. Секция расположений окон, в том числе на различных столах
 ----------------------------------------------------------------------------------------
 -- Стандартные расположения
 -- Tall разделение по вертикали на главную и вспомогательную части
 -- Mirror Tall - раделение по горизонтали на главную и вспомогательную части
 -- Full -полноэкранное расположение, переключение между окнами mod+tab

 -- Для каждого монитора, в мултимониторной конфигурации (Xinerama) может быть
 -- несколько рабочих столов
 -- Для каждого стола может быть несколько расположений (one-to-many,1-N)
 -- перечисление (выбор) задается оператором |||, а расположения помещаются в скобки

 -- Сейчас один монитор


 расположение =   
    onWorkspace стол_разное ( общее_расположение ||| сеточное_расположение ) $
    onWorkspace общий_стол общее_расположение $
    onWorkspace стол_просмотра общее_расположение $
    onWorkspace стол_фото расположение_для_gimp $
    onWorkspaces [стол_интернет, стол_сервер] расположение_на_весь_экран $
    общее_расположение ||| общее_горизонтальное_расположение ||| расположение_на_весь_экран
  where
   общее_расположение = spacing 5 $ Tall master delta ratio
   общее_горизонтальное_расположение = spacing 5 $ Mirror $ Tall master delta ratio
   defaultTall = ResizableTall 1 (3/100) (1/2) []
   master = 1
   ratio = 2/3
   delta = 3/100
   расположение_на_весь_экран = smartBorders $ Full 
   сеточное_расположение = spacing 6 $ Grid
   расположение_для_gimp = simpleDeco shrinkText цветовое_оформление $ defaultTall


 ---------------------------------------------------------------------------------------
 --   IV. Секция заглушек для специфической обработки программ, всплывающих окон и пр.
 ----------------------------------------------------------------------------------------

 -- Это то место, где можно настроить  поведение при запуске сложных многооконных программ
 -- Для определения класса окна, надо запустить специальную программу xprop
 --
 -- className =? "Firefox"
 -- title =? "Firefox"
 -- appName =? "Firefox"
 -- (getStringProperty "WM_ROLE") =? "Roster window"

 -- Сложные программы для размещения, это мессенджеры, gimp и т.п.

 поведение_программ = composeAll      
      [ поведение_браузеров
      , поведение_просмотрщиков
      , поведение_почтовых
      , для_калькулятора
      , для_скайпа
      , для_файлового_менеджера
      , для_менеджера_фотографий
      , для_minitube
      , для_gimp
      , className =? "File Operation Progress" --> разместить_по_центру_стола 
      , resource =? "desktop_window" --> doIgnore
      , поведение_диалоговых_окон           
      ]
          where
     положить_на = doShift

 положить_на = doShift
 разместить_по_центру_стола = doCenterFloat

-- Для диалоговых окон - размещение по центру, плавающими
 

 поведение_диалоговых_окон =
    isDialog --> разместить_по_центру_стола

 поведение_браузеров =
    className =? "Firefox"
    --> doShift стол_интернет

 поведение_просмотрщиков =
        className =? "evince"
        --> положить_на стол_просмотра

 поведение_почтовых =
     className =? "Evolution"
     --> положить_на стол_почты

 для_калькулятора =
    appName =? "gcalctool"
    --> разместить_по_центру_стола

 для_скайпа =
    appName =? "skype"
    --> положить_на стол_разное

 для_файлового_менеджера =
    appName =? "nautilus"
    --> положить_на стол_разное
 для_менеджера_фотографий =
    appName =? "shotwell"
    --> положить_на стол_фото
 для_minitube =
        appName =?  "minitube"
        --> положить_на стол_просмотра


 -- Графический редактор GIMP
 -- 2 режима отображения поддерживается: отдельные окна и однооконный
 -- Однооконный режим позволяет использовать Gimp в компоновке полного экрана
 -- Многооконный режим надо настраивать поведение отдельных оконных ролей
 -- главное окно изображения WM_WINDOW_ROLE(STRING) = "gimp-image-window"
 -- панель вкладок WM_WINDOW_ROLE(STRING) = "gimp-dock"
 -- панель инструментов WM_WINDOW_ROLE(STRING) = "gimp-toolbox"
 для_gimp =
    className =? "Gimp"
    --> (положить_на стол_фото)


 ----------------------------------------------------------------------------------------
 --    V. Секция оформления (цвета, шрифты и т.п.)
 ----------------------------------------------------------------------------------------
 -- Определения цветов задаются в 24-битном пространстве RGB

 цвет_рамки_выделенного_окна  = "#68e862"
 цвет_рамки_обычного_окна     = "#60A1AD"

 цветовое_оформление = defaultTheme

    { activeColor         = "orange"    -- цвет активного окна
    , inactiveColor       = "#222222"    -- цвет неактивного окна
    , urgentColor         = "yellow"    -- не знаю
    , activeBorderColor   = "orange"    -- цвет рамки активного окна
    , inactiveBorderColor = "#222222"    -- цвет рамки неактивного окна
    , urgentBorderColor   = "yellow"    -- цвет рамки какого-то окна
    , activeTextColor     = "black"    -- цвет текста активного окна
    , inactiveTextColor   = "#222222"    -- цвет текста неактивного окна
    , urgentTextColor     = "yellow"    -- цвет текста какого-то окна
    , fontName           = "-*-terminus-bold-*-*-*-16-*-*-*-*-*-*-u" -- шрифт
    -- , decoWidth      = 100
    , decoHeight          = 20
    , windowTitleAddons = [("<<<", AlignRight)] -- Заголовок окна и его размещение
    -- , windowTitleIcons    = []
    }

 -- Сформировать строку шрифта можно с помощью программы xfontsel

 ----------------------------------------------------------------------------------------
 --   VI. Секция привязки клавиш
 ----------------------------------------------------------------------------------------

 -- Доступные операции можно найти в XMonad.Operations
 -- http://www.haskell.org/haskellwiki/Xmonad/Key_codes
 -- Константы клавиш можно посмотреть в Graphics/X11/ExtraTypes/XF86.hsc

 -- Используемые клавиши модификаторы (Ctrl,Shift,Alt,Win и т.п.)

 -- shiftMask
 -- сontrolMask
 -- mod1Mask
 -- mod4Mask

 -- Клавиши управления менеджером окон XMonad
 -- Т.к. много мониторов, на каждом много столов, у которых много расположений
 -- то предусмотрим клавиши для циклического переключения
 управляющие_клавиши = [
    ((mod4Mask, xK_space),nextWS)            -- переключает на след. стол
    -- , ((altMask, xK_space), prevWS)        -- переключает на пред. стол
    , ((mod1Mask, xK_space), sendMessage NextLayout)  -- переключает на другое расположение, на текущем столе
    , ((mod4Mask, xK_Down), nextWS)            -- переключение на след. стол
    , ((mod4Mask, xK_Up), prevWS)            -- переключение на пред. стол
    -- переключает на другой монитор
    ]

 -- Мультимедийные клавиши управления звуком

 мультимедийные_клавиши = [
       ((0, xF86XK_AudioLowerVolume), kill)        -- уменьшает громкость
     , ((0, xF86XK_AudioRaiseVolume), kill)        -- увеличивает громкость
     , ((0, xF86XK_AudioMute), kill)            -- выключает звук
        ]

 -- Это набор для моей текущей клавиатуры
 -- Клавиши запуска приложений
 клавиши_запуска = [
      ((0, xF86XK_Close), kill)            -- Закрыть окно   
    , ((0, xF86XK_HomePage), spawn "firefox http://gimmor.blogspot.com/")    -- Web/Home
     , ((0, xF86XK_Mail), spawn "evolution")        -- Почта
    , ((0, xF86XK_Calculator), spawn "gcalctool")    -- Калькулятор
    , ((0, xF86XK_LogOff), spawn "gcalctool")    -- Выйти из съянса (не работает)
    , ((0, xF86XK_Sleep), spawn "gcalctool")    -- Спящий режим
       , ((0, xF86XK_Launch1), spawn "gcalctool")    -- Проверка
    , ((0, xF86XK_Favorites), spawn "nautilus")    -- Файлы
    , ((0, xF86XK_Messenger), spawn "skype")    -- Мессенджер
    ]

 -- Мои функциональные клавиши

 функциональные_клавиши = [
    ((0,xF86XK_Reply), spawn "gcalctool")         -- Ответ
    , ((0,xF86XK_Send), spawn "gcalctool")         -- Отправка
    , ((0,xF86XK_New), spawn "gcalctool")         -- Новое окно
    , ((0,xF86XK_Save), spawn "gcalctool")         -- Сохранение
    , ((0,xF86XK_MailForward), spawn "gcalctool")     -- Пересылка
    , ((0,xF86XK_Open), spawn "gcalctool")         -- Не работает
    , ((0,xK_Help), spawn "gcalctool")         -- Справка по Xmonad
    , ((0,xK_Print), spawn "scrot")          -- Скриншот экрана
    ]


 все_клавиши = concat [
    управляющие_клавиши,
    мультимедийные_клавиши,
    клавиши_запуска,
    функциональные_клавиши
    ]


 -- Клавиши для удаления
 
 удаляемые_клавиши = [ (mod4Mask .|. shiftMask, xK_c) 
      , (mod4Mask .|. shiftMask, xK_j) 
      , (mod4Mask .|. shiftMask, xK_k) 
      , (mod4Mask, xK_j) 
      , (mod4Mask, xK_k) 
      , (mod4Mask, xK_h) 
      , (mod4Mask, xK_l) 
      , (mod4Mask, xK_comma) 
      , (mod4Mask, xK_period) 
      ]

 ----------------------------------------------------------------------------------------
 --  VII. Секция привязки кнопок мыши
 ----------------------------------------------------------------------------------------
 -- клавиши_мыши = [ ((mod4Mask, button4),\_-> spawn "amixer set Master 3%+") 
 --     ,((mod4Mask, button5),\_-> spawn "amixer set Master 3%-") 
 --     ,((mod4Mask, button3),\_-> return()) 
 --     ,((mod4Mask, button1),\_-> return()) 
 --     ]

-----------------------------------------------------------------------------------------
--   VIII. Секция автозагрузки
-----------------------------------------------------------------------------------------



 ----------------------------------------------------------------------------------------
 --   IX. Секция конфигураций
 ----------------------------------------------------------------------------------------

 -- Моя конфигурация на основе конфигурации по-умолчанию

 рабочая_конфигурация = defaultConfig
     { manageHook = manageDocks
        <+> поведение_программ
                 <+> manageHook defaultConfig
     , layoutHook = avoidStruts $ расположение
     , terminal = "gnome-terminal --hide-menubar"
     , modMask = mod4Mask  -- меняем привязку клавиши, вместо alt будет  win
     , workspaces = рабочие_столы
     , normalBorderColor = цвет_рамки_обычного_окна
     , focusedBorderColor = цвет_рамки_выделенного_окна
     , borderWidth = 4
     , startupHook = return ()
     }  `additionalKeys` все_клавиши
        `removeKeys` удаляемые_клавиши
    -- `additionalMouseBindings` клавиши_мыши

 -- Экспериментальная конфигурация, для проверки разных возможностей
 экспериментальная_конфигурация = defaultConfig
     { manageHook = manageDocks
                <+> поведение_программ
                <+> manageHook defaultConfig
     , layoutHook = avoidStruts $ расположение
     , terminal = "urxvt"
     , modMask = mod4Mask      -- меняем привязку клавиши, вместо alt будет  win
     , workspaces = рабочие_столы
     }


 ----------------------------------------------------------------------------------------
 --    X. Секция главной функции main - точки входа в программу
 ----------------------------------------------------------------------------------------

 main = do
   spawn "setxkbmap -layout 'us,ru' -option grp:ctrl_shift_toggle -option grp_led:scroll"
   -- xmproc <- spawnPipe "/usr/bin/xmobar"
   xmonad $ рабочая_конфигурация



----------------------------------------------------------------------------------------
-- Дополнительная информация
----------------------------------------------------------------------------------------
-- Если при запуске xmonad не работает переключение клавиатуры
-- то временно исправить можно выполнив:
-- setxkbmap -layout "us,ru" -option grp:ctrl_shift_toggle -option grp_led:scroll


-- Ресурсы
-- http://www.haskell.org/haskellwiki/Xmonad/General_xmonad.hs_config_tips
--




Всё.
Чтобы оставить клавишу alt в качестве клавиши mod, надо убрать строку:

, modMask = mod4Mas
из рабочей конфигурации.
 

Плюсы XMonad

- Возможность настройки рабочего окружения и его сохранения между перезагрузками
- Возможность интеграции с окружением рабочего стола Gnome
- Возможность посмотреть на язык Haskell


Минусы XMonad

- Необходимость настройки начальной конфигурации
- Необходимость смотреть на язык Haskell
- Необходимость установить компоненты рабочего стола X Window - такие как Tray (trayer), StatusBar (xmobar), Menu (), Lock и соответственно настроить их взаимодействие
- Сложность настройки, например многооконных программ
- Неожиданности, для некторых программ


Выводы

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


Осталось за кадром, подключение полосок состояний (xmobar, dzen), конфигурация gimp в многооконном режиме, различные интересные дополнения [см. Ресурсы п.14], повышающие удобство, автозагрузка рабочих программ.



Ресурсы

1. Официальный сайт языка Haskell. http://haskell.org/
2. О языке Haskell на Wikipedia. http://ru.wikipedia.org/wiki/Haskell
3. Описание Haskell 98 (на русском языке). http://www.haskell.ru/
4. Учебник по языку Haskell (на русском языке). http://anton-k.github.com/ru-haskell-book/book/home.html
5. Мягкое введение в haskell. http://www.rsdn.ru/article/haskell/haskell_part1.xml
6. Почему никто не использует функциональные языки. http://www.softcraft.ru/paradigm/fp/whynotfp.shtml
7. Hackage - свободная библиотека пакетов программ (функций). http://hackage.haskell.org/packages/hackage.html
8. Как выглядит XMonad. Снимки экрана. http://www.haskell.org/haskellwiki/Xmonad/Screenshots
9. Документация модуля xmonad. http://xmonad.org/xmonad-docs/xmonad/index.html
10. XMonad FAQ. http://www.haskell.org/haskellwiki/Xmonad/Frequently_asked_questions
11. Xmonad Tips. 
12. Настройка XMonad. http://ro-che.info/docs/xmonad/
13. Расширения XMonad. http://xmonad.org/xmonad-docs/xmonad-contrib/
14. Описание расширений XMonad и их применение (en). http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Doc-Extending.html

15. Как Eax.me познакомился с xmonad. http://eax.me/xmonad/
16. Цвета текста и фона в Bash. http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
17. Примеры конфигураций Xmonad: http://www.haskell.org/haskellwiki/Xmonad/Config_archive
18. Пользователи делятся информацией о Xmonad. http://www.linux.org.ru/tag/xmonad?offset=20

воскресенье, 11 ноября 2012 г.

Мой dotfile .bashrc. Пополняемая заметка

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

Общесистемный конфигурационный файл: /etc/bashrc
Пользовательский конфигурационный файл: $HOME/.bashrc

Самое простое - Псевдонимы - Aliases

Псевдонимы задаются следующим образом:
alias псевдоним=shell - команда с параметрами

alias homepage='firefox http://gimmor.blogspot.com/'
alias домой='cd $HOME'

без пробелов, вокруг "=".

пятница, 9 ноября 2012 г.

пятница, 2 ноября 2012 г.

Скрипт BASH как фильтр. Bash script as filter

Возникла потребность превратить скрипт BASH в скрипт - фильтр, т.е. тот скрипт, который можно использовать в цепочке конвейера.

 #!/bin/bash
# Скрипт-фильтр
# gimmor.blogspot.com
# 02.11.2012

# Читаем со стандартного входа, пока не получим конец файа, либо пользователь не нажмет "ctrl D".
# читаем символьные строки, а не бинарные

while read myline; do 

# Выводим на стандартный вывод
echo myline

done

Вместо эха, можно использовать свою обработку.

Теперь, можно делать так:

$ head file | cut -f 1 | sort | uniq | ./myfilter.sh | grep "somthing" > outputfile

Вроде чуть прояснилось.

вторник, 30 октября 2012 г.

Часть IV. Предварительные меры для восстановления данных. Pre-fail. Saved data.

В связи с переходом к использованию LVM, GPT, RAID технологий для хранения пользовательских данных, настоятельно возникла внутренняя тревога - беспокойство о их сохранности.

Т.к. объем используемых винчестеров превысил 1ТБ, и количество данных сохраняемых на одном винчестере возросло. Возросло так, что даже простое копирование файлов с винчестера на винчестер отнимает день - два и это при подключении по SATA. Правда и при подключении по USB, сроки такие-же. Это "благодаря" миллиону мелких файлов, которые резко снижают производительность копирования, местами до 10 МБ/c, а десятка легко "пролезает" через usb.

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

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

Следующую важную роль играет хладнокровие пользователя, столкнувшегося с отказом системы хранения данных. У меня например, когда я случайно затираю что-то ценное, резко приливает кровь к голове. Через несколько минут, постепенно проходит. Правда резервные копии имеются, но не всегда доступные (далеко).
В такие моменты, главное не начать, "впопыхах" восстанавливать данные. Я практикую способ, пойти прогуляться, подышать воздухом. Можно на балкон. Т.е. отвлечься и начать думать.

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

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

Эта заметка пополняемая со временем.

Мероприятия по сохранению информации

Все эти мероприятия, выполняются до отказа хранилища и способствуют разнообразным целям при восстановлении данных, при оценке ущерба от потери данных.

1. Сохранение структуры разметки. Разметка диска меняется очень редко. И даже её, трёхлетняя твердая копия, с данным о границах разделов, может помочь составить первоначальное представление.
Очень важно, иметь на одном листе - идентификационные данные диска и структуру разметки. Дополнительные данные, такие как дата, местоположение диска и др. имеют смысл. Т.к. по прошествии времени, очень много забывается.

2. Структура разметки не дает информации о применявшихся файловых системах на разделах. Эту информацию также надо извлечь заранее и сохранить в понятном виде, распечатать.

3. Для вложенных разметок (LVM) также доступными системными средствами, извлечь и сохранить и распечатать информацию о конфигурации.

4. Составление списка файлов тома. Для редко изменяемых томов хранения, полезным будет составить список всех файлов хранящихся на томе.

5. Составление контрольных сумм файлов тома. Эта операция по длительности может превысить разумные сроки. Возможно выборочное, для особо ценных файлов. Требуется мощный процессор.

6. При разметке дисков, желательно следовать стандартам (см. Часть I).

7. Для хранения наиболее важных данных, использовать самую простую и понятную лично файловую систему, опыт взаимодействия с которой показал её надежность в разнообразных жизненных ситуациях.

8. Для хранения важных файлов, не следует использовать различные сжимающие программы. Т.к. сжатие данных - это превращение известной структуры файла в неизвестную. А существующие архивы, если это позволяет их содержимое, распаковывать. Например, очень часто файлы пришедшие по электроной почте, через Интернет, упакованы для уменьшения передаваемого объема. Смысла хранить их в таком виде, обычно нет. Они недоступны для поиска (обычно), сложны (невозможны) для восстановления.

9. Построение и настройка системы резервного копирования. Например, RAID-1 тянет за собой покупку 3 дисков, минимум. 2 - в RAID, 1 - для резервной копии. А ещё, он должен быть отлючен, а это внешняя коробка.

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

11. Выключение операционной системы, по возможности, проводить корректно, а не выдергиванием кабеля.

12. Настройка мониторинга дисков по аттрибутам SMART, для выявления на ранней стадии, сбоя.

13. Разделение данных. "Холодные" данные, хранить в дефрагментированном виде. "Горячие" данные, выносить в отдельные диски, массивы, резервы.

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

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

16. Применять файловые системы, резервирующие свои служебные области, в нескольких местах на диске.

17. Следовать ограничениям применяемых файловых систем и находить их пересекающееся множество, чтобы не иметь проблем с переносом файлов. Очень часто, превышение длины имени файла, приводит к невозможности его копирования из одной точки монтирования (пр. NTFS том), в другую (EXT4).

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

19. Защитите данные Ext4 от удаления: chattr +i

20. Не проводить операций с разделами, установками на дисках, хранящих данные. Установщики - программы легко повреждающие целевой диск, даже по неосторожности, по недопониманию, по встроенной логике, не соответствующей вашей логике разметки.

21. Тренируйтесь с копиями данных, в другой системе, а не в системе хранения.

22. Реже обновляйте, дабы не перевести хранилище в состояние "оффлайн". Обновление автоматическое, это да, а вот навыки и особенности конфигурирования сервера забываются и не автоматические.

23. Подбор файловой системы хранилища под задачи. О, это целая тема.

24. Помните, что приход AF (Advanced format) жестких дисков, увеличил единицу хранения диска до 4KB, с одновременным сокращением контрольных данных (ECC-кодов блока) до 1%, против 512 байт старого формата и ~10% кодов восстановления. Единица потери увеличилась в 4 раза, а спообность винчестера справляться с ошибкой уменьшилась в ~10 раз. Следовательно, мероприятия по сохранению данных легли на вышестоящий уровень.



Выводы

- Учёт и репликация


Ресурсы

1. Сравнение файловых систем. http://ru.wikipedia.org/wiki/%D0%A1%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2%D1%8B%D1%85_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC


Мониторинг микросервера с помощью настройки TMUX

Компьютерная жизнь микросервера (HP Proliant microserver) протекает неспешно, с временами переконфигурирования и далее опять неспешно.
Т.к. микросервер работает без монитора, без мыши, без клавиатуры, то соответственно нет привычного графического интерфейса. Остается одна лишь консоль, по ssh-подключению.
И вот эту, простую чёрную консоль, можно превратить в удобнейший рабочий стол, по управлению микросервером.

Консоль - Терминал - Интерфейс командной строки - CLI.


Мультиплексирование терминала - TMUX - terminal multiplexing

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

После настройки, пользователю останется только не забыть способ навигации внутри tmux.

Более того, tmux можно использовать вместо командной оболочки при заходе на сервер. Сразу настроенная среда.

Внутри tmux, можно использовать вместо обычного bash, любую другую оболочку, либо интерпретаторы языков высокого уровня.


Краткий обзор TMUX
Общесистемный конфигурационный файл: /etc/tmux.conf
Пользовательский конфигурационный файл: ~/.tmux.conf
Произвольный конфигурационный файл, задается опцией -f, при запуске tmux.
Руководство (en): man tmux

Запуск: tmux [команда]

Установка в Ubuntu server: $ sudo apt-get install tmux


Префикс по умолчанию, для управления с клавиатуры: ctrl-b

Поддерживаются несколько буферов обмена, мышь.

Сессии tmux

Сессий может быть много. Имена и логическое назначение выбирает пользователь.
Например, сессии - общий мониторинг микросервера (microserver), общий мониторинг сети (network), мониторинг и управление сервисами (services), управление удаленными вебсерверами (webservers), баз данных (database).

В принципе, для любого системного сервиса можно использовать сессию, либо окно внутри сессии.

Система адресации в Tmux

сессия  - [имя сессии]
окно     - [сессия]:[имя окна]
панель - [сессия]:[окно].[номер панели]

примеры:

сессия  - microserver
окна     - microserver:control      microserver:logfiles
панели - microserver-control.0   microserver.logfiles.2



Команды tmux

$ tmux new-session -n [имя окна] -s [имя сессии]

сессия создаётся с окном по умолчанию, для задания имени такого окна используется опция -n. Опция -s задает имя сессии. Опция -d - запуск сессии в фоне (daemon-режим).

$ tmux new-window -n [имя окна] -t [имя сессии] [скрипт]

создается новое окно внутри сессии, например:

$ tmux new-window -a -n logfiles -t microserver
(просто окно, без команды)
опция -a указывает окно делается с индексом следующим за текущим в данной сессии
[скрипт] - командный файл, который будет выполнен во вновь созданном окне.


$ tmux new-window -a -n logfiles -t microserver "top"
(выполниться команда top во вновь созданном окне)

По умолчанию выполняется приглашение оболочки. Если выполнить [скрипт], то окно закроется, чтобы не закрывалась (нужно иногда), надо установить опцию: remain-on-exit = on в конфигурационном файле.
Если не планируется закрывать такое окно, то можно использовать и такую форму запуска.

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

пример:
# tmux send-keys -t network:real.2 "slurm -i home.8" C-m
в сессию network, окно real, панель №2, набрать "slurm -i home.8" и нажать ввод "C-m"


Рабочее окружение на основе TMUX

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

#!/bin/bash
# сервер: microserver, микросервер, n40l
# 30.10.2012

# Сессии
# microserver - общая сессия, для разнообразных работ на сервере
# services - сессия наблюдения за сервисами микросервера
# network - сессия наблюдения за домашней сетью

tmux new-session -d -n control -s microserver
tmux new-session -d -n s-view -s services
tmux new-session -d -n n-view -s network

# В каждой сессии создается свой набор окон, помимо первых окон.
# окна logfiles предназначены для просмотра логфайлов
tmux new-window -a -n logfiles -t microserver
tmux new-window -a -n logfiles -t services
tmux new-window -a -n logfiles -t network

# Делим первое окно (control) в сессии microserver
# По горизонтали на 2 панели, правую панель по вертикали на 2
tmux split-window -dv -p 50 -t microserver:control.0
tmux split-window -dh -p 50 -t microserver:control.1

# Делаем небольшоое окошко командной строки
tmux split-window -dv -p 10 -t microserver:control.2

# Делим второе окно (logfiles) в сессии microserver
# 4 панели - четверти экрана
# Вначале, делим текущее окно пополам, потом появившуюся панель
# с номером 1 пополам, а затем остаток от панели 0 пополам.
tmux split-window -dh -p 50 -t microserver:logfiles.0
tmux split-window -dv -p 50 -t microserver:logfiles.1
tmux split-window -dv -p 50 -t microserver:logfiles.0

# Делаем небольшоое окошко командной строки
tmux split-window -dv -p 10 -t microserver:control.2

# Выбираем окно по умолчанию, в сессии microserver
tmux select-window -t microserver:control


Базовая система навигации TMux

Префикс по умолчанию, для управления с клавиатуры: ctrl-b
Его можно перенастроить в конфигурационном файле (переназначить).

Отсоединение от терминала tmux: ctrl-b d
Присоединение к терминальной сессии: tmux attach-session -t microserver

Переключение между окнами сессии, по номеру: ctrl-b 0, ctrl-b 1


Перемещение между панелями: ctrl-b и стрелки курсора
Показать индексы панелей: ctrl-b q
Также можно выбрать панель по индексу: ctrl-b q 1

Можно изменять размеры панелей: нажимаете ctrl-b, затем отпускаете b, но держите ctrl и стрелками курсора двигаете.

Закрыть окно, панель: набрать exit

Вращение панелей: ctrl-b o, удерживая ctrl
Может быть полезно, когда надо "одним глазом" присматривать за происходящим на панели, но, её размер уменьшить до разумного минимума, а когда возникнет в ней необходимость - повернуть, чтобы она заняла место крупной панели, сделать нужное и повернуть обратно.

Переключение (attach) сессий не выходя из текущей сессии: ctrl-b s


Дополнительный команды навигации см. man tmux

Баги TMUX

Если в TMUX вывести огромный текстовый файл, то TMux перестает реагировать на команды.
Вывод, либо лечить патчами, либо не выводить большие файлы, либо дождаться завершения вывода.


Интересные консольные приложения для TMux


Хвосты файлов - Tail, Multitail

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

Визулизация траффика по интерфейсу - Slurm

$ slurm -i home.8

Список процессов -Htop

$ htop


Доступность сети - sntop

$ sntop
Конфигурационный файл sntop: /etc/sntoprc
Чрезвычайно полезна вещь, особенно когда сеть достаточно разветвленная, но небольшая. Сеть тестируется с помощью периодического ping.
"Зелененькое хорошо, красненькое плохо".


Именованные конвейеры - Named pipes - байтопровод

Именованные конвейеры - средство межпроцессного взаимодействия в Linux/Unix. Могут быть чрезвычайно полезны в связке с фреймовыми менеджерами и мультиплексированными терминалами.
Изготавливаются командой: mkfifo
Пример позже, а пока можно сказать, что их удобно использовать для связывание вывода и ввода программ.


Фреймовые оконные менеджеры Awesome, XMonad

Аналогичные рабочие окружения можно создать с помощью фреймовых оконных менеджеров для систем X Window.
Принцип управления сохраняется, добавляются возможности вывода графических приложений.


Выводы

- Подход к использованию мультиплексирования терминала, фреймовых оконных менеджеров, отличается от привычных действий, требует вдумчивой и достаточно длительной настройки. Результат будет великолепный.
- Мощь программы tmux раскрывается запускаемыми консольными приложениями, способом представления информации, подбором информации и продумыванием управления.


Ресурсы

-. Официальный сайт TMux. http://tmux.sourceforge.net/
-. Cool unix tools. http://kkovacs.eu/cool-but-obscure-unix-tools-. http://wiki.fornex.com/index.php/Команды_Linux
-. Жизнь в консоли. http://welinux.ru/blog/115/
-. http://debiania.blogspot.ru/2010/05/nohup-dtach-screen-tmux.html
-. Пятерка фреймовых оконных менеджеров. http://help.ubuntu.ru/fullcircle/37/top5_37

-. Awesome в Ubuntu. http://help.ubuntu.ru/wiki/awesome

суббота, 27 октября 2012 г.

Часть III. Перенос системы на другой диск. MBR-to-GPT.

Возникла задача перенести установленную систему Ubuntu Server 12.04 на микросервере, находящуюся на комплектном жестком диске на другой диск, в зарезервированный раздел(ы).

Про разметку дисков микросервера можно посмотреть в заметке о GPT - LVM - RAID - 3TB.

Комплектный жесткий диск (250ГБ), был размечен, в своё время, установщиком Ubuntu Server, в автоматическом режиме, а это таблица разделов MBR, да еще и с логическими разделами. Это непорядок, тем более,сейчас осуществляю переход на GPT, чтобы снять ограничения.

Целевой 3ТБ жесткий диск Seagate ST3000DM001, размечен в современную разметку GPT.  На нём существуют специально выделенные разделы под основную и резервные Linux системы.

Трудности переноса Ubuntu на другой диск (миграция MBR на GPT)

Просто копирование файлов не помогает. В Linux есть специальные файлы и каталоги. Для них специальный подход. Также, т.к. современные Linux системы имеют дело с уникальными идентификаторами GUID, то и для них, - специальных подход.

HP Proliant Microserver N40L имеет обычный BIOS, а не современную систему UEFI. Поэтому, микросерверу для загрузки нужен диск с разметкой MBR.
Комплектный диск был размечен в MBR и нормально загружался. Но для повышения гибкости микросервера, он будет преобразован.
Разметка в MBR на современных дисках, с 4KiB физическими секторами, влечёт падение производительности, из-за устаревших требований MBR разметки - начало раздело кратно 63 сектору.

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

Задача

Перенести систему с комплектного загрузочного диска на 3TБ диск в один из зарезервированных ранее разделов для Ubuntu Linux. Попутно, разделить систему, данные системы и пользовательские данные. После этого, преобразовать комплектный жесткий диск в GPT. Перенести только систему обратно. После этого, создать загрузочный том на маленькой флешке, с загрузчиком GRUB2, для загрузки системы либо с 3TБ диска, либо с 250ГБ.
По максимуму, забыть про MBR и более не размечать диски в ней.

Флешку можно подключить к внутреннему разъему микросервера, а можно просто повесить сзади микросервера, вынув её после загрузки.

Исполнение

Для переноса системы, можно выполнить загрузку с другого носителя, приостановив работу микросервера.Загружаюсь с usb-ssd.
Далее, понадобятся 4 (в моём случае) точки монтирования.Одна укажет путь к корневой системе исходного (250ГБ) диска, вторая - путь к корневой системе целевого раздела 3ТБ диска, третья - путь к разделу home целевого раздела 3 TБ, четвертая - путь к разделу данных.

Перенос будет состоять из нескольких этапов.
1. Форматирование целевого раздела корневой файловой системы (/), в EXT4.
2. Форматирование целевого раздела домашней папки (/home), в EXT4.

. Простое копирование простых файлов корневой файловой системы исходного диска
. Перенос полезных данных из папки /home исходного раздела, в папку на раздел данных. Т.к. сейчас полезные данные, не относящиеся к микросерверу храняться внутри папки /home, в подпапках.
. Простое копирование остатков папки home, в целевой раздел. Перенос данных относящихся к микросерверу на раздел /home на целевом диске.
. Изменение необходимых файлов на целевом разделе: цель: /etc/fstab,
. Создание специальных каталогов и специальных файлов
- Настройка загрузки

Итак, целевой диск, в моём случае 3ТБ: /dev/sda
Раздел корневой системы целевого диска, будущая точка монтирования (/): /dev/sda7
Раздел домашней папки. будущая точка монтирования (/home): /dev/sda8.
Раздел подкачки (swap), будущей системы: /dev/sda4.

Форматирование
Форматирование - очень опасная операция, часто приводящая к случайной порче полезных данных, по невнимательности. На свой страх и риск.

Форматирование 2 разделов, одной строкой, с указанием меток:

# mkfs.ext4 -L two-root /dev/sda7 && mkfs.ext4 -L two-home  /dev/sda8

Также, т.к. форматирование делается вначале пути, не лишнем будет ознакомиться с файловой системы ext4, почитать про возможности.

Монтирование

Монтирование отформатированных целевых разделов, в точки временного монтирования. Можно примонтировать в путь /mnt/two-root /mnt/two-home, можно в иные места, не суть. Единственно что можно заметить здесь, это использовать короткие имена точке монтирования, дабы не превысить ограничение длины пути в Linux.

# mkdir /mnt/two-root
# mkdir /mnt/two-home
# mount -t ext4 /dev/sda7 /mnt/two-root
# mount -t ext4 /dev/sda8 /mnt/two-home


Перенос корневой файловой системы (корня,root).

Можно пойти несколькими путями. Использовать утилиту tar, утилиту rsync, простое копирование (cp-ax), dump/restore.
Но, при любом способе, надо контролировать следующие условия: права файлов, даты файлов и каталогов, жесткие и мягкие ссылки, именованные каналы, сокеты, точки монтирования, специальные файловые системы.

Точки монтирования (например дисков с пользовательскими данными), должны исключаться из копирования (при переносе корня), либо должны предварительно быть отмонтироваными. Известные точки монтирования: /mnt - /media /home Специальные файловые системы /dev /sys /proc. Но конечный список определятся местными условиями.


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

Учебный пример: перенос файлов содержащих .backup в имени, в другую папку, посредством утилиты tar (последовательный архив):

# tar -c --exclude=place1 *.backup | tar -x --directory=/mnt/two-home/

здесь опции:
-c - создание архива
--exclude= - исключение объектов по шаблону
*.backup - это файлы которые будут архивироваться
| - символ конвейера (pipe) в Linux/Unix, перенаправление вывода команды слева в команду справа.
-x - извлечение архива
--directory= - смена каталога, на тот куда будет произведено извлечение архива
Работает tar  в каталоге запуска и копирует все файлы с расширением backup.


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

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

Если требуется более безопасный способ, то тогда проводить архивацию в файл, а потом из файла восстанавливать на целевой точке монтирования.


Рабочий пример микросервера: перенос корневой системы
т.к. у меня 1 раздел, на котором и root и home, то при копировании root, я исключаю home, и копирую потом отдельно.

Прежде чем копировать, надо оценить имеющееся место на целевом разделе.

Всё копирование, делаем из каталога источника, чтобы избежать указания длинных путей.
# cd /mnt/src-root

# tar -cp --exclude=home --exclude=proc --exclude=sys --exclude=dev --exclude=mnt --exclude=media . | tar -x --directory=/mnt/two-root

Также, я отдельной командой скопировал каталог конфигураций etc, были какие-то сложности.
# tar -cp  etc | tar -x --directory=/mnt/two-root

Скопировал содержимое папки home (а не саму папку), в корень будущего раздела /home:

# tar -cp --exclude=backup  home/* | tar -x --directory=/mnt/two-home

Также, я отдельной командой скопировал папку backup из каталога home в другое место

# tar -cp home/backup | tar -x --directory=/mnt/backup


Выяснение UUID:
# blkid | grep sda7
 dev/sda7: LABEL="two-root" UUID="7fd88c8d-6ec2-4142-94ff-b70987654321" TYPE="ext4"
# blkid | grep sda8
 dev/sda7: LABEL="two-home" UUID="7fd88c8d-6ec2-4142-94ff-b71234567890" TYPE="ext4"

Редактирование /etc/fstab на целевом разделе:
# nano /mnt/two-root/etc/fstab

Замена UUID точек монтирования / и /home на полученные на предидущем этапе. Монтирование по уникальному идентификатору раздела, позволяет, например, переставить жесткие диски (а они тут же поменяют имена устройств) и спокойно, ядру, загрузить корневую файловую систему и домашнюю.
Каждая точка монтирования на своей строке, добавить комментарии - дату изменения, метку системы, что делалось.

Раздел подкачки указал просто устройство, т.к. uuid не нашел (раздел не форматированный) - /dev/sda4

Выдержка из fstab:

# <file system> <mount point>   <type>  <options>       <dump>  <pass>

proc            /proc           proc    nodev,noexec,nosuid 0       0

UUID=7fd88c8d-6ec2-4142-94ff-b70987654321 /               ext4    errors=remount-ro 0   1

UUID=7fd88c8d-6ec2-4142-94ff-b71234567890 /home           ext4    errors=remount-ro 0   1

# временно указано устройство, а не UUID
/dev/sda4       none    swap    sw      0       0


Создание точек монтирования специальных файловых систем:
# mkdir /mnt/two-root/proc
# mkdir /mnt/two-root/sys
# mkdir /mnt/two-root/dev

Обычные точки монтирования:
# mkdir /mnt/two-roor/media
# mkdir /mnt/two-roor/mnt


В принципе, на этом этапе, всё, можно воспользоваться обновлением загрузчика (update-grub) на текущей запущенной системе, он обновиться, найдет новые системы и пропишет строки запуска и попробовать перезагрузиться в новую систему, используя стартовый носитель (usb-ssd), как загрузчик.
# update-grub
Найден Ubuntu 12.04.1 LTS (12.04) на /dev/sda7
Найден openSUSE 11.4 (x86_64) на /dev/sdc2
Найден Ubuntu 12.04.1 LTS (12.04) на /dev/sde1


Новая сформированная система (резервная копия основной системы микросервера) найдена на /dev/sda7.
Откопался даже эксперимент с OpenSuse на каком-то дискe, про который я уже и забыл :-)
Также откопалась основная система микросервера на комплектном диске /dev/sde1.
Просто загрузчик на новом диске, ещё не знал, про наличие других систем и мог загрузить только свою.


А можно, заняться установкой загрузчика, но с дисками GPT - это нетривиальный процесс. Т.к. на микросервере BIOS, то нужен диск размеченный в MBR - у меня будет флешка.
В микросервере, есть удобная функциональность, стандартный внутренний USB-порт на плате. Туда подключу флеш-накопитель. Размечу его в MBR.
Сделаю несколько разделов.
Первый раздел, выделю для загрузчика. Второй раздел выделю для образа дополнительного загрузочного диска. Третий раздел - либо UDF, либо exFAT. Пока не решил, как будет.

Установка загрузчика GRUB2 на загрузочный том (флешку)

Загрузчику нужно где-то хранить свои файлы. GRUB2 хранит обычно в папке /boot/grub, иногда просто /grub.

Загружаемся в любой системе, желательно поновее (12.10).

Инсталляция загрузчика выполняется командой grub-install, с опциями.

Флешка у меня в этот раз, была /dev/sdf

# fdisk /dev/sde
Диск /dev/sde: 7743 МБ, 7743995904 байт
113 головок, 57 секторов/треков, 2348 цилиндров, всего 15124992 секторов
Units = секторы of 1 * 512 = 512 bytes
Размер сектора (логического/физического): 512 байт / 512 байт
I/O size (minimum/optimal): 512 bytes / 512 bytes
Идентификатор диска: 0x000be372

Устр-во Загр     Начало       Конец       Блоки   Id  Система
/dev/sde1              63      392672      196305   83  Linux



Boot раздел флешки (/dev/sde1) был примонтирован в /media/iam/boot.

Выполняем установку загрузчика GRUB2:

# grub-install --boot-directory=/media/iam/boot /dev/sdf

Этим мы меняем поведение установщика и он, вместо текущего корня, устанавливае Grub 2 в указанную директорию (файлы GRUB2, конфигурационный файл, меню и пр.), а в само устройство /dev/sdf прописывает загрузочный boot-sector.

Теперь надо обновить список операционных систем, доступных для загрузки, сгенерировав главный конфигурационный файл GRUB2, следующей командой:

# grub-mkconfig -o /media/iam/boot/grub/grub.cfg

Может возникнуть вопрос, почему не update-grub. Update-grub обновляет по умолчанию файл, /boot/grub/grub.cfg, а этот файл находится в корне загруженной системы. А это нам не надо, хотя можно тоже освежить.

Далее, я выключаю микросервер, отключаю диск с которого шла загрузка и включаю микросервер. В BIOS выставляю опцию - загрузки с USB и гружусь.
Если всё правильно, то появиться меню загрузчика и будет список готовых для загрузки операционных систем. Выбираю загрузку установленной настольной системы Ubuntu Gnome 12.10 (на /dev/sdb5).
Также, после перезагрузки проверяю загружаемость микросервера с комплектного диска, с резервной системы на диске /dev/sda7.

Замеченная особенность, загрузочная флешка автомонтируется при запуске графического рабочего стола Gnome Shell. Если её отключить, то перезагрузка не сработает и надо выключить микросервер, чтобы заработало.
В принципе, её можно убрать из автомонтирования, либо не отключать - самое простое.

Соединение GPT и MBR в Hybrid MBR

Технология нестандартная, но используемая. Существенным недостатком является, то что вся настройка (долгая) может легко слететь при любой установке, любой системы. Обычно через время, всё это забывается и благополучно переписывается. Системы проверки корректности структуры разметки, также могут не понять режим Hybrid MBR и исправить ошибку :-)
Существенным плюсом, не требуется флешка для загрузки с GPT дисков.
Если есть желание, то можно потренироваться [см. Ресурсы.1].

Использование rsync для переноса корневой системы

Rsync также может быть использован для переноса корневой системы [см. Ресурсы п. 2].


Как-то так:
# rsync -qaHEAXh --progress --exclude 'home' --exclude 'dev' --exclude 'proc' --exclude 'sys' --exclude 'media' --exclude 'mnt' /mnt/src-root/* /mnt/two-root 
потом и для home.

Часто практикуется синхронизация рабочей копии системы с резервной по расписанию.

Ну и обратная операция, когда всё проверено и работает так как надо, можно приступить к форматированию комплектно диска в GPT и обратный перенос. Файл заметки большой, а команд не так много.
При обратной операции попробую rsync.

Всё.



Ресурсы

1. Hybrid MBR. http://www.rodsbooks.com/gdisk/hybrid.html
2. Перенос Ubuntu на другой винчестер. http://lin.in.ua/articles/2-Debian/4-Opisanie_processa_perenosa_Ubuntu_Debian_na_drygoj_vinchester.html
3. О выравнивании разделов. http://www.linux.org.ru/wiki/en/%D0%92%D1%8B%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%BE%D0%B2_%D0%B4%D0%B8%D1%81%D0%BA%D0%B0




пятница, 26 октября 2012 г.

Добавление сетевого принтера. Microserver-network-printer

В Gnome Shell 3.6 продолжаются проблемы у встроенной утилиты добавления принтера, находящейся в "Системные параметры".

Для добавления сетевого принтера во вновь установленном Gnome shell, я использую системный скрипт:
/usr/share/system-config-printer/system-config-printer.py

Alt+F2 и ввести строку.

Это запускает обычный диалог добавления принтера в Ubuntu:



system-config-printer в Gnome Shell 3.6

Принтер легко находится по сети, если задать hostname сетевого принтера.



либо web-страницу (homepage) CUPS:

http://localhost:631

CUPS homepage


Принтер на микросервере

Для добавления принтера в микросервере, надо установить текстовый броузер elinks, либо настройть web-интерфейс CUPS.

Чтобы принтер, HP Color LaserJet CM1015 MFP был принтером на микросервере, надо установить HPLIP (пакет hplip)
Чтобы принтер HP LaserJet 1018 поддерживался, надо установить драйвер Foo2ZJS (пакет foo2zjs)
Чтобы был виртуальный принтер CUPS-PDF, надо установить пакет cups-pdf.


# apt-get install cups cups-pdf hplip foo2zjs

Далее воспользоваться wb-страницей для добавления принтера. Web-страница принтеров, с других компьютеров сразу недоступна. Надо исправить в /etc/cups/cupsd.conf на микросервере.

Установить Port 631 вместо Listen localhost:631
Добавить разрешения вида: Allow 192.168.1.0/255.255.255.0
в секции:
<Location />
  Order allow,deny
  Allow localhost
  Allow 192.168.1.0/255.255.255.0
</Location>
<Location /admin>
  Order allow,deny
  Allow localhost
  Allow From 192.168.1.0/255.255.255.0
</Location>
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
  Allow localhost
  Allow From 192.168.1.0/255.255.255.0
</Location>

Т.е. разрешить компьютерам из локальной сети (192.168.1.0/24), заходить на страницу администрирования.

Для печати из командной строки, надо установить пакет lpr.

# apt-get install lpr

Печатать так:

# cat file | lpr