В этой статье я хотел бы рассказать как можно создавать сценарии сборки имиджей для Docker контейнеров с помощью системы многоцелевых сценариев Sparrow*.



(*) Примечание — для понимания некоторых технических нюансов данной статьи желательно иметь хотя бы поверхностное знакомство с системой многоцелевых сценариев Sparrow, краткое введение в которую ( помимо страниц документации ) можно найти в моей предыдущей статье на habrahabr.ru.


Разработка Docker контейнеров


Вначале немного проблематики. Имеем задачу описать сборку Docker имиджа с помощью Dockerfile. Если сценарий сборки нетривиален и содержит множество инструкций, нужно как-то выкручиваться. Помимо того, что Dockerfile не может содержать более 120 слоев ( насколько я правильно понял из документации по Docker ), иметь дело с развесистым Dockerfile не очень приятно. Что можно с этим поделать? Очевидные варианты — вынести код сборки в отдельные Bash скрипты в рабочую директорию и делать установку и настройку системы прямо из них. Другой способ — "прикручивать" сбоку какой-нибудь configuration management tool типа chef или ansible. Оставляю на откуп читателю оценку данных альтернатив ( IMHO у них есть свои плюсы и минусы ) и предлагаю третий способ — использование Sparrow.


Прежде чем приводить детали реализации хочется сказать:


  • Вариант со Sparrow чем-то то очень похож на использование Bash скриптов, с той лишь разницей, что вся логика установки выносится в Sparrow плагин, со своим исходным кодом, хранящимся в отдельном месте ( git репозитарий или центральное хранилище ).


  • Таким образом, базовая настройка системы в контексте Docker описана в Dockerfile, а более тонкая и сложная внутри Sparrow плагина.


  • Разработка плагина может быть отделена от контекста Dockerfile — что удобно, например вы можете на существующем Docker контейнере отлаживать процесс установки, на прибегая каждый раз к постройке имиджа командой docker build, и, как только плагин будет отлажен и готов к работе, можно еще раз прогнать полный цикл сборки системы посредством все той же командой docker build ( сбросив при этом docker кэш разумеется ).

Пример реализации


Итак, покажем все на конкретной системе. Требуется собрать имидж с дистрибутивом CentOS и установить приложение, написанное на Ruby версии равной 2.3. После этого запустить основной скрипт приложения из под выделенного пользователя. Исходный код приложения скачивается с некого архивного сервера. Пример взят из реальной жизни, хотя некоторые детали намеренно опущены, дабы не перегружать статью материалом.


Базовая конфигурация системы


Прежде чем писать код плагина, создадим Dockerfile. За базовый имидж я взял tutum/centos по причине его легковесности. По этой же причине приходится доставлять часть пакетов, но в целом это не является какой-то проблемой.


$ cat Dockerfile

FROM tutum/centos

MAINTAINER "melezhik" <melezhik@gmail.com>

RUN yum clean all
RUN yum -y install nano git-core
RUN yum -y install make
RUN yum -y install gcc

RUN yum -y install perl perl-devel perl-Test-Simple perl-Digest-SHA perl-Digest-MD5 perl-CPAN-Meta perl-CPAN-Meta-Requirements perl-Getopt-Long perl-JSON perl-Module-CoreList perl-Module-Metadata perl-parent perl-Path-Tiny perl-Try-Tiny perl-App-cpanminus perl-JSON-PP perl-Algorithm-Diff perl-Text-Diff perl-Spiffy perl-Test-Base perl-YAML perl-File-ShareDir-Install perl-Class-Inspector perl-File-ShareDir perl-File-ShareDir-Install perl-Config-General

RUN cd /bin/ && curl -L https://cpanmin.us/ -o cpanm && chmod +x cpanm

RUN cpanm Sparrow -q

Немного комментариев по Dockerfile .


  • nano и git-core необходимы для разработки Sparrow плагина ( смотрите далее ) — мы будем редактировать код сценариев и коммитить изменения в удаленный git репозитарий.


  • gcc, make потребуются для сборки RubyGems и CPAN пакетов. Первые потребуются при установки Ruby через rvm, последние для установки Sparrow.


  • Установка многочисленных perl-* пакетов через yum необходима для оптимизации процесса сборки по скорости, можно было бы не делать этого, т.к. следующая инструкция cpanm -q Sparrow установила бы требуемые зависимости сама, но установка зависимостей через cpanm в общем случае требует гораздо больше времени, чем установка "нативных" для CentOS rpm-ок.


  • Инструкция cpanm Sparrow -q ставит среду разработки многоцелевых сценариев, не забываем, что мы собираемся разрабатывать Sparrow прямо на запущенном Docker контейнере.

Итак, попробуем создать имидж:


$ docker build -t ruby_app .

 ...
 ...

 Successfully built 25e7cd784c99

Начинаем разрабатывать плагин


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


$ docker run -t -i ruby_app /bin/bash

$ mkdir ruby-app
$ cd ruby-app
$ git init .
$ git remote add origin https://github.com/melezhik/ruby-app.git
$ touch README.md
$ git add README.md
$ git config --global user.email "melezhik@gmail.com"
$ git config --global user.name "Alexey Melezhik"
$ git commit -a -m 'first commit'
$ git push -u origin master

Вышеуказанными командами мы создали шаблон проекта для нашего плагина и закоммитили все в удаленный git репозитарий. URL репозитария мы запомним, он понадобится нам далее, когда мы будем проводить полноценную сборку имиджа командой docker build


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


  • Создание аккаунта пользователя приложения
  • Установка Ruby посредством rvm
  • Скачивание архива приложения, распаковка и установка зависимостей

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


$ nano hook.bash

action=$(config action)

for s in $action
do
    run_story $s
done

set_stdout install-ok

$ nano story.check

 install-ok

Немного комментариев по коду. Мы имеем три второстепенных истории ( модули ) и одну основную, заданную хук файлом (hook.bash), для того, что показать как все это работает создадим заглушки для сценариев в модулях. Да, и дефолтное значение для входного параметра action должно быть задано в suite.ini файле.


$ nano suite.ini

action create-user install-ruby install-app

Создаем заглушки сценариев:


$ mkdir -p modules/create-user   
$ mkdir -p modules/install-ruby   
$ mkdir -p modules/install-app   

$ nano modules/create-user/story.bash
echo create-user-ok

$ nano modules/install-ruby/story.bash
echo install-ruby-ok

$ nano modules/install-app/story.bash
echo install-app-ok

А также проверочные файлы:


$ nano modules/create-user/story.check
create-user-ok

$ nano modules/install-ruby/story.check
install-ruby-ok

$ nano modules/install-app/story.check
install-app-ok

Теперь запустим все через strun — консольный скрипт для выполнения Sparrow сценариев:


$ strun
/tmp/.outthentic/93/ruby-app/story.t ..
# [/ruby-app/modules/create-user]
# create-user-ok
ok 1 - output match 'create-user-ok'
# [/ruby-app/modules/install-ruby]
# install-ruby-ok
ok 2 - output match 'install-ruby-ok'
# [/ruby-app/modules/install-app]
# install-app-ok
ok 3 - output match 'install-app-ok'
# [/ruby-app]
# install-ok
ok 4 - output match 'install-ok'
1..4
ok
All tests successful.
Files=1, Tests=4,  0 wallclock secs ( 0.00 usr  0.02 sys +  0.09 cusr  0.01 csys =  0.12 CPU)
Result: PASS

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


Сценарий создания пользователя


Будем исходить из того что имя пользователя является настраиваемым, дефолтное значение определяем в файле suite.ini :


$ cat suite.ini
action create-user install-ruby install-app
user_name app-user

Теперь реализация сценария:


$ nano modules/create-user/story.bash

user_id=$(config user_name)

echo create user id: $user_id

useradd -r -m -d /home/$user_id $user_id || exit 1

ls -d /home/$user_id || exit 1

id $user_id || exit 1

echo create-user-ok

И запуск ( обратите внимание, что здесь мы воспользовались возможностью запуска отдельного сценария с помощью параметра action ):


$ strun  --param action=create-user

/tmp/.outthentic/135/ruby-app/story.t ..
# [/ruby-app/modules/create-user]
# create user id: app-user
# /home/app-user
# uid=997(app-user) gid=995(app-user) groups=995(app-user)
# create-user-ok
ok 1 - output match 'create-user-ok'
# [/ruby-app]
# install-ok
ok 2 - output match 'install-ok'
1..2
ok
All tests successful.
Files=1, Tests=2,  0 wallclock secs ( 0.03 usr  0.00 sys +  0.11 cusr  0.04 csys =  0.18 CPU)
Result: PASS

Мы видим, что сценарий отработал и пользователь создался. Обратите внимание, что большинство Bash команд внутри сценария завершаются идиоматической конструкцией cmd || exit 1, strun проверяет код выполнения сценария и если он неуспешен, то соответствующий тест проваливается, например так — попробуем создать пользователя с невалидным для системы именем:


$ strun  --param action=create-user --param user_name='/'
/tmp/.outthentic/160/ruby-app/story.t ..
# [/ruby-app/modules/create-user]
# create user id: /
# useradd: invalid user name '/'
not ok 1 - scenario succeeded
not ok 2 - output match 'create-user-ok'
# [/ruby-app]
# install-ok
ok 3 - output match 'install-ok'
1..3

#   Failed test 'scenario succeeded'
#   at /usr/local/share/perl5/Outthentic.pm line 167.

#   Failed test 'output match 'create-user-ok''
#   at /usr/local/share/perl5/Outthentic.pm line 213.
# Looks like you failed 2 tests of 3.
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/3 subtests

Test Summary Report
-------------------
/tmp/.outthentic/160/ruby-app/story.t (Wstat: 512 Tests: 3 Failed: 2)
  Failed tests:  1-2
  Non-zero exit status: 2
Files=1, Tests=3,  0 wallclock secs ( 0.02 usr  0.00 sys +  0.10 cusr  0.00 csys =  0.12 CPU)
Result: FAIL

Сделаю здесь еще небольшое отступление. Зададимся вопросом зачем нам нужно проверочные файлы, если по-сути проверки кода завершения сценария должно быть достаточно. Резонный вопрос. Мы можем думать о проверочных правилах фреймворка Sparrow как о некой альтернативном способе контроля или верификации выполнения наших скриптов. В идеологии Sparrow любой выполняемый сценарий является историей в том смысле, что это некий скрипт, который запускается и чаще всего "сообщает" что-то о своей работе — образно говоря "оставляя след в истории". Это след — стандартный выходной поток stdout, содержимое которого можно провалидировать. Почему это может быть полезно:


  • Не всегда успешный код завершения означает, что все идет хорошо


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

В качестве конкретного примера можно привести сценарий установки Ruby через rvm, который идет следующим по списку в нашем плане.


Сценарий установки Ruby из rvm


Вот как будет выглядеть сценарий установки:


$ nano modules/install-ruby/story.bash

yum -y install which

curl -sSL https://rvm.io/mpapis.asc | gpg2 --import - || exit 1

\curl -sSL https://get.rvm.io | bash -s stable --ruby || exit 1

source /usr/local/rvm/scripts/rvm

gem install bundler --no-ri --no-rdoc

echo ruby version: $(ruby --version)

bundler --version

echo install-ruby-ok

А это — проверочный файл:


$ nano modules/install-ruby/story.check

regexp: ruby version: ruby 2\.3
install-ruby-ok

Теперь запустим данный сценарий:


$ strun --param action=install-ruby

# большая часть вывода
# здесь опущена
# ...
# ...
# ...
# ruby version: ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
# Bundler version 1.12.5
# install-ruby-ok
ok 1 - output match /ruby version: ruby 2\.3/
ok 2 - output match 'install-ruby-ok'
# [/ruby-app]
# install-ok
ok 3 - output match 'install-ok'
1..3
ok
All tests successful.
Files=1, Tests=3, 91 wallclock secs ( 0.03 usr  0.00 sys +  3.24 cusr  1.03 csys =  4.30 CPU)
Result: PASS

Хочется обратить внимание, что для верификации версии установленного Ruby мы воспользовались проверочным правилом ввиде регулярного выражения:


regexp: ruby version: ruby 2\.3

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


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


Сценарий установки приложения


Напомню. Нам будет необходимо:


  • скачать тарбол по заданному урлу
  • распаковать архив
  • перейти в распакованную папку и выполнить команду bundle install --target ./local для установки зависимостей

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


Опять таки же для простоты примера пусть у нас есть Ruby приложение состоящее из:


  • Gemfile — в котором будут прописаны зависимости
  • hello.rb — запускаемого скрипа, который просто выводит в консоль строчку Hello World

Пакуем все архив и выкладываем все на архивный сервер га локальный nginx, теперь дистрибутив будет доступен по URL:


127.0.0.1/app.tar.gz

Обновим код сценария.


$ cat suite.ini

action create-user install-ruby install-app
user_name app-user
source_url 127.0.0.1/app.tar.gz

$ cat modules/install-app/story.bash

user_id=$(config user_name)
source_url=$(config source_url)

yum -y -q install sudo

echo downloading $source_url  ...
sudo -u $user_id -E bash --login -c "curl -f -o ~/app.tar.gz $source_url -s" || exit 1

echo unpacking tarball ...
sudo -u $user_id -E bash --login -c "cd ~/ && tar -xzf app.tar.gz" || exit 1

echo installing dependencies via bundler
sudo -u $user_id -E bash --login -c "cd ~/app && bundle install --quiet --path vendor/bundle " || exit 1

sudo -u $user_id -E bash --login -c "cd ~/app && bundle exec ruby hello.rb " || exit 1

echo install-app-ok

$ nano modules/install-app/story.check

install-app-ok
Hello World

Небольшие комментарии по сценарию:


  • Установку делаем из-под пользователя заданного в конфигурации плагина suite.ini. Для этого нам нужен пакет sudo


  • Последняя команда запускает скрипт приложения hello.rb


  • В проверочном файле требуем что бы в stdout был виден "след" от сценария — строчка 'Hello World'

Итак, запустим сценарий:


$ strun --param action=install-app
/tmp/.outthentic/16462/ruby-app/story.t .. 
# [/ruby-app/modules/install-app]
# Package sudo-1.8.6p7-17.el7_2.x86_64 already installed and latest version
# downloading 127.0.0.1/app.tar.gz ...
# unpacking app ...
# installing dependencies via bundler
# Hello World
# install-app-ok
ok 1 - output match 'install-app-ok'
ok 2 - output match 'Hello World'
# [/ruby-app]
# install-ok
ok 3 - output match 'install-ok'
1..3
ok
All tests successful.
Files=1, Tests=3,  2 wallclock secs ( 0.01 usr  0.00 sys +  1.61 cusr  0.50 csys =  2.12 CPU)
Result: PASS

Как мы видим приложение действительно установилось и скрипт hello.rb запускается. Добавим еще один "параноидальный" ассерт в проверочный файл для демонстрации возможностей системы проверок Sparrow:


$ nano modules/install-app/story.check

install-app-ok
Hello World

generator: <<CODE
!bash
if test -d /home/$(config user_name)/app; then
  echo assert: 1 directory /home/$(config user_name)/app exists
else
  echo assert: 0 directory /home/$(config user_name)/app exists
fi
CODE

И запустим сценарий заново.


$ strun --param action=install-app

В выводе получим:


$ ok 3 - directory /home/app-user/app exists

Публикация Sparrow плагина


На этом создание плагина завершено. Закоммитим изменения и сделаем "push" в git репозитарий:


$ git add .
$ git commit -a -m 'all done'
$ git push
$ exit

Мы вышли из докер контейнера он нам больше не нужен, можно его удалить:


$ docker rm 5e1037fa4aef

Полный цикл сборки имиджа для Docker контейнера


Осталось чуть-чуть изменить Dockerfile, вспоминаем о том, что нам понадобится ссылка на удаленный git репозитарий, где мы разместили код нашего Sparrow плагина, окончательный вариант будет таким:


FROM tutum/centos

MAINTAINER "melezhik" <melezhik@gmail.com>

RUN yum clean all
RUN yum -y install nano git-core
RUN yum -y install make
RUN yum -y install gcc

RUN yum -y install perl perl-devel perl-Test-Simple perl-Digest-SHA perl-Digest-MD5 perl-CPAN-Meta perl-CPAN-Meta-Requirements perl-Getopt-Long perl-JSON perl-Module-CoreList perl-Module-Metadata perl-parent perl-Path-Tiny perl-Try-Tiny perl-App-cpanminus perl-JSON-PP perl-Algorithm-Diff perl-Text-Diff perl-Spiffy perl-Test-Base perl-YAML perl-File-ShareDir-Install perl-Class-Inspector perl-File-ShareDir perl-File-ShareDir-Install perl-Config-General

RUN cd /bin/ && curl -L https://cpanmin.us/ -o cpanm && chmod +x cpanm

RUN cpanm Sparrow -q

RUN echo ruby-app https://github.com/melezhik/ruby-app.git > /root/sparrow.list

RUN sparrow plg install ruby-app

RUN sparrow plg run ruby-app

Теперь мы можем осуществить полный цикл сборки имиджа, "проиграв" все заново:


$ docker build -t ruby_app --no-cache=true .

В итоге мы получим Docker имидж с требуемой системой.


Заключение


Применение системы многоцелевых сценариев Sparrow может быть эффективным средством построения Docker имиджей, т.к. позволяет строить сложные конфигурации, оставляя основной Dockerfile простым и лаконичным, а так же упрощая процесс разработки самих сценариев конфигурирования требуемой системы.


Спасибо за внимание.


Как обычно жду вопросов и конструктивной критики! :)


Алексей

Поделиться с друзьями
-->

Комментарии (67)


  1. alexkunin
    02.06.2016 19:03
    +1

    Простите, я не понял основную идею, даже после беглого прочтения главной страницы репозитория спарроу.

    Если все, что делает спарроу — выполнение сценария, то почему класть в репозиторий именно спарроу-сценарий, а не просто баш скрипт? А если так, то почему бы не зашить баш-скрипт непосредственно в Dockerfile, который и положить в репозиторий? А заодно подхучить его к докер хабу и получить автобилды. И получится, что вся информация о контейнере внутри одного конкретного файла, а не разибита по нескольким репозиториям.

    Можете в двух словах киллер-фичность такого подхода описать, пожалуйста?

    Из статьи понятно, как это сделать, но не ясно (мне) зачем. Вроде как спарроу — это средство управления сценариями-конфигурациями-рецептами (в контексте, скажем, конфигурирования сервера), но ведь докер делает то же самое своим Dockerfile. Вижу отдельную фичу тестирование — может в ней весь цимес?


  1. SirEdvin
    02.06.2016 20:22

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


  1. alexey_melezhik
    02.06.2016 21:03

    Приветствую! Попытаюсь ответить на два последних комментария одним своим комментом. Да, вы правы, впринципе обычных bash скриптов может быть достаточно для написания конфигурационных сценариев. Sparrow это по сути и есть некоторые скрипты, которые можно запустить. Окей, не просто скрипты конечно же, Sparrow предлагает дополнительные ( killer? ;-) фичи из коробки:


    • скрипты можно писать на одном из трёх языков — Perl, Ruby, Bash, последний был выбран мной при написании статьи, но выбор им не ограничивается


    • вне зависимости какой из языков вы используете, из коробки гарантировано Sparrow API, на который вы можете положится, а именно: 1) входные данные в виде конфигурационных файлов (yaml, Config::General ) или параметров командной строки 2) модульность — возможность вызывать одни сценарии из других с передачей параметров ввиде хэшей ( попробуйте это сделать на снуля на bash ) 3) встроенная система тестирования сценариев Outthentic::DSL

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


    Ещё пара важных фич Sparrow, нераскрытых здесь:


    • отчеты Sparrow предоставляются в формате TAP, переносимом на многи системы


    • Sparrow плагины — переносимые пакеты пользовательских скриптов, имеющие свои версии и распространяемые через центральный репозитарий https://sparrowhub.org, в данной статье я использовал вариант с так называемыми приватными плагинами, которые устанавливаются через удаленные git репозитории, но в общем случае вы всегда можете опубликовать в публичный доступ, все это поощряет повторное использование кода в контексте конфигурационных пользовательских скриптов, аналогия chef рецепты или ansible плейбуки, толко sparrow плагины более общие в том смысле они не навязывают никакого DSL при их написании ( как в случае с шефом или ансиблом ) идеология Sparrow такова вы выбираете комфортный для вас язык разработки( сейчас это один из трёх — Perl, Ruby или Bash, впрочем добавление других типа Python илиGo не так сложно ) а Sparrow просто добавляет все вышеперечисленные фичи и дань возможность опубликовать ваши сценарии и распространять их ввиде пакетов. ( sparrow плагинов )

    Вообщем как то так ...


    1. alexkunin
      02.06.2016 22:45

      Perl, Ruby, Bash

      Спарроу тащит все три зависимости внутрь? Кстати, можно же писать на них и без спарроу.

      На счет конфигурации, в мире докера вроде принято делать все через переменные окружения. Их можно группировать в файлы .env (идеально совмещаются с docker-compose) и/или передавать через командную строку.

      Вот тестирование — интересно, хотя не ясно, что тестировать в случае инсталляционного скрипта. Ведь вы что-то скриптуете относительно известной и фиксированной версии ОС.

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


      1. alexey_melezhik
        02.06.2016 23:07

        Спарроу тащит все три зависимости внутрь? Кстати, можно же писать на них и без спарроу.

        Нет конечно. Изначально только Perl, т.к. Sparrow на нем написан. Он ставится как cpan модуль ( в будущем может соберу rpm,deb ) — и зависимостей у него не так много от других cpan модуйлей


        Насчет остального — предполагается, что ruby или bash доступен в системе, плюс возможность подгружать зависимости при установки именно плагинов ( а не самого Sparrow ) — т.е. пользователь может определить свои зависимости от CPAN, rubygems посредством файлов cpanfile или Gemfile


        На счет конфигурации, в мире докера вроде принято делать все через переменные окружения. Их можно группировать в файлы .env (идеально совмещаются с docker-compose) и/или передавать через командную строку.

        Sparrow этому не противоречит, в статье я как раз и пытался это выразить. Т.е. базовые настройки можно проталкивать через Dockerfile конвекционно. Но, что, если у нас сложная конфигурация с иерархической структурой ( вложенностью ), боюсь, что переменные окружения здесь будут неудобны, а вот Sparrow умеет из коробки работать со сложными конфигурационными файлами в формате Config::General или YAML, причем независимо от языка на котором пишется сценарий


        Вот тестирование — интересно, хотя не ясно, что тестировать в случае инсталляционного скрипта. Ведь вы что-то скриптуете относительно известной и фиксированной версии ОС.

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


        • проверить что процесс существует (виден) в списке процессов
        • проверить контент файла

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

        Да, да. В этом и фишка Sparrow. Вы пишите что-то сложное и нестандартное ( а таких задач на самом деле немало ) — потом пакетируете это в виде Sparrow плагина и выкладываете на https://sparrowhub.org — теперь другие могут использовать это. Примеры плагинов — https://sparrowhub.org/search


  1. alexey_melezhik
    02.06.2016 23:17

    прошу прощения, опечатался в предыдущем комментарии:


    вы валидируете stdout от вашего тестового сценария


  1. alexey_melezhik
    02.06.2016 23:22

    да и вот еще важный момент, простите не сразу сообразил :)


    Кстати, можно же писать на них и без спарроу.

    В этом и суть, Sparrow и не является еще одним языком или DSL, все верно, вы изначально пишите на каком-то из трех языков, а потом с минимальными усилиями портируете свой набор скриптов ( или один скрипт ) в Sparrow плагин, получая те самые фичи о которых я говорил в предыдущих комментариях.


  1. MaverickCGRey
    03.06.2016 07:53

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

    Подумал. Прочитал ещё раз… Малость испугался.

    А вы точно уверены, что вам необходимы такие развесистые «скрипты развертывания»? Может что-то не так с самой идеей такой сложной настройки образа?

    P.S. А можно ли какой-то пример из вашей практики, чтоб ощутить необходимость такого сложного контейнерного образа?


    1. alexey_melezhik
      03.06.2016 08:28

      Например, сборка приложений со сложными конфигурациями, где необходимо использование шаблонизаторов. Или пробрасывание кастомных yum репозитариев, или приложения где используется одновременно несколько языков программирования, среды для которых нужно строить с нуля.


      Но суть использования Sparrow не в том, что все тоже самое нельзя написать в терминах только Dockerfile. Sparrow подход ортогонален Docker проектам, вы можете например написать плагин для установки Ruby,rvm и использовать этот плагин в разных Docker проектах. А если все то же самое написано прямо в Dockerfile или даже внутри bash скрипта это становится сложно переносить и повторно использовать, особенно об этом я писал тут.


      1. MaverickCGRey
        03.06.2016 17:15

        Дополнительные вопросы после off-хабр обсуждения.

        1. Правильно ли я понял, что вы таки используете Docker образы в своём проекте?
        2. Являются ли созданные вами образы независимыми от окружения, в котором они будут запускаться? Может ли один и тот же образ быть запущен локально (или в тестовом окружении) и на production?
        3. Включаете ли вы секреты в образ или же они запрашиваются в момент старта контейнера?
        4. Я не знаком с Ruby. Правильно ли я понял, что eye оборачивает ruby-процесс и для вас выглядит как некий launcher — вы запускаете его, а он запускает ваш ruby код?

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

        Следуя аналогии дедушки Мартина (Fowler), такой сложный образ начинает отдавать душком (smells). Возможно вам стоит разбить один образ на несколько и запускать их как совокупность?

        Вот тут про то, как образы могут быть декомпозированы в kubernetes — http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html Но мне кажется, всё то же самое может сделать Docker Compose.


        1. alexey_melezhik
          03.06.2016 20:15

          1. начинаем, правильнее будет сказать


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


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


          4. eye один супервизор ( написан на ruby имеет ruby API ) — коих десятки — он просто следит за системными процессами ( не обязательно связанными с ruby приложением, за любыми )

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

          не вопрос, можно растащить все на отдельные имиджи и потом делать "наследование" через FROM:, Sparrow опять таки же не противоречит этой концепции — вы можете:


          1) иметь отдельные части системы на уровне вложенных докер образов — первая степень свободы


          2) вы можете деплоить отдельные части системы — отдельными sparrow плагинами — вторая степень свободы


          вы сами выбираете в какой степени вы больше сдвигаетесь в сторону 1) или в сторону 2), и да могут быть частные случаи когда вы используете только 1) или только 2), но что-то мне подсказывает что истина в том, что зачастую комбинировать оба подхода гораздо удобнее и эффективнее


        1. alexey_melezhik
          03.06.2016 20:44

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


          декомпозированы

          здесь те же мысли, что и при использование докера по схеме, указанной alexkunin в https://habrahabr.ru/post/302278/#comment_9642488 (см. также мой ответ ему ), даже при должной декомпозиции и разбиении системы на более простые куски, самый простой кусочек может аналогично деплоится через sparrow плагин или плагины ( в зависимости таки от сложности кусочка ), кроме того, при таком подходе можно получить чистую и никак не связанную с самими докером (по крайней мере сильно ) систему строительных блоков ( плагинов ) — "параллельную" множеству имиджей, используемых в системе…


    1. alexkunin
      03.06.2016 14:52

      На счет слоев, часто вижу такое в официальных докер-образах (в их Dockerfile):

      RUN command 1 &&     command 2 &&     command 3
      

      Т.е. команда большая и сложная, но слой будет только один.

      Еще часто кладут рядом какой-нибудь setup.sh и entrypoint.sh, в котором можно удобнее-красивее логику реализовать: первый через ADD/RUN запускают, второй — через ADD/CMD/ENTRYPOINT.

      Т.е. 120 слоев не проблема даже при развесистых скриптах.


      1. alexey_melezhik
        03.06.2016 15:13

        да, конечно, все так.


        но на мой взгляд использование \ ну по крайней мере черезмерное усложняет читаемость докерфайла, но да не в этом дело, как уже сказал, что можно все вынести в сторонние bash скрипты и потом использовать их ( будь то ADD, CMD, ENTRYPOINT ) — но по сравнению со Sparrow — эти скрипты будут жестко привязаны к контексту конкретного Docker проекта, вот, например вы захотите их использовать повторно в другом проекте, что бы не писать все сначала, или сделать какой-нибудь рефакторинг, что бы выделить базовые вещи, общие для разных проектов ( сборок ) — в случае с прямым подходом Dockerfile/bash/ADD/CMD/ENTRYPOINT это будет сделать гораздо сложнее, чем со Sparrow — т.к. в нем by desing предусмотрена модульность и переносимость скриптов. Sparrow в этом смысле более гибок и агностичен где он используется ( Docker или любые другие задачи автоматизации ), а bash скрипты как есть — IMHO- хороши для решения задачи здесь и сейчас — но сложны для повторного использования и дистрибуции, т.е. в перспективе с ними могут быть проблемы на большом кол-ве проектов.


        Да, и повторюсь еще раз. В контексте сборок Docker контейнеров Sparrow — это те же Bash скрипты, с идеей их простого повторного использования ( + плюс встроенная система конфигурации скриптов — suite.ini / yaml ) в других проектах ...


        1. alexkunin
          03.06.2016 15:46

          В общем, по-прежнему не хватает того самого примера, где были бы очевидны преимущества использования Sparrow.

          Может, набросаем такой пример? Может, вам же он и пригодится — на странице проекта упомянете.

          Есть идеи, что можно было бы эдакое в контейнер завернуть?


          1. alexey_melezhik
            03.06.2016 15:50

            :) Интересно, нужно подумать. Прямо сейчас должен отлучится. А давайте может так… У вас есть какие-нибудь задачи по конфигурации? Что-нибудь сложное? :)) Приведите здесь исходные данные, напишем вместе Sparrow plugin вместе с Dockerfile :)…


            1. alexkunin
              03.06.2016 15:58

              Да нет, у меня все просто, PHP приложение в контейнере с апачем, в отдельных контейнерах mysql, beanstalkd. Относительная сложность присутствует на уровне docker-composer.yml, но это ведь уже не то.

              Вот пример докерфайла для девбокса, часть на пхп под апачем (лично для себя делал, команда докером не пользуется):

              FROM ubuntu:14.04
              
              RUN apt-get update
              RUN apt-get dist-upgrade -y
              RUN apt-get install -y ca-certificates
              RUN apt-get install -y apache2
              RUN apt-get install -y libapache2-mod-php5
              RUN apt-get install -y php5
              RUN apt-get install -y php5-mysql
              RUN apt-get install -y php5-curl
              RUN apt-get install -y php5-memcached
              
              RUN a2enmod rewrite
              
              RUN echo "<VirtualHost *:80> \\n    DocumentRoot /app/proj/public \\n    ErrorLog /dev/stdout \\n    CustomLog /dev/stdout combined \\n    <Directory /app/proj/public> \\n        AllowOverride All \\n        Require all granted \\n    </Directory> \\n</VirtualHost>" > /etc/apache2/sites-available/000-default.conf
              
              VOLUME /app/proj
              WORKDIR /app/proj
              ENTRYPOINT ["/bin/sh", "-c"]
              CMD ["apache2ctl -D FOREGROUND"]
              EXPOSE 80
              EXPOSE 443
              

              В общем, развернуться негде.


              1. alexey_melezhik
                03.06.2016 19:06

                Спасибо за ваш пример. А само приложение ( на php, как я понимаю? ) как деплоится?


                1. alexkunin
                  03.06.2016 19:13

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

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

                  Более сложным примером докерфайла не обладаю, к сожалению.


                  1. alexey_melezhik
                    03.06.2016 19:43

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


                    • разделить деплой на три части — деплой зависимостей (php, apache, и все остальные пакеты ), настройка самого апача и деплой приложения


                    • тогда если скажем у вас бы было несколько проектов вы могли бы как минимум части первую и вторую использовать повторно


                    • а вот что бы пункт предыдущий был осуществим я бы через Sparrow сделал бы это так:

                    1) плагин basic-app (ну или какое нибудь более удачное название ) — для деплоя первой части системы


                    2) плагин apache-config (для настройки и запуска апача ) — часть вторая


                    3) плагин(ы) app-*-install (для деплоя различных php приложений ) — часть третья


                    С помощью монолитных Dockerfiles это было бы сделать более проблематично — или пришлось много копировать повторяющихся кусков кода.


                    Вот как-то так.


                    Т.е. я к тому, что сложность она не только в том, что отдельные компоненты сложно настраивать, а и в том, что зачастую один и тот же типовой компонент (basic, apache и т.д.) может потребоваться поставить больше чем одни раз на множество контейнеров, серверов, классика жанра для devops )))…


                    1. alexkunin
                      03.06.2016 19:58
                      +1

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

                      Собственно, даже в этом проекте есть еще один докерфайл для контейнера с воркерами. Там идентичный ПХП, только без апача (все это под supervisord). В настоящий момент я просто скопировал кусок докерфайла, но если бы был менее ленив (или более мотивирован заказчиком, которому вообще начхать как я запускаю свой сервак), я бы сделал как сказал выше — общий базовый образ.

                      Вот тут мы вплотную подходим к ключевому отличию: базовый образ может быть только один, т.е. нет множественного наследования. А Спарроу — это что-то вроде миксинов, т.е. суррогатное множественное наследование.

                      Проблема только в том, что в докере принято в одном контейнере реализовывать один четкий компонент системы (даже вот апач+пхп не есть гуд, нужно бы отдельно апач привязать к отдельно фаст-цги пхп; но часть системы — вордпресс, он хочет .htaccess, и тут у меня не получилось красиво все разделить). Т.е. множественное наследование не должно образоваться, или мы что-то делаем не так.

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

                      Разве что мне нужно одновременно деплоить и в докер, и просто на машину (дали ссш на боевой сервер — действуй!), и в виртуалку (т.е. опять просто на машину). Но тут нужно хорошенько обосновать необходимость такого мультидеплоя. Я пока оснований не вижу. В моей собственной ситуации как раз и есть этот мультидеплой, но только потому, что я хотел поиграться с докером на живом проекте (и доигрался — теперь за уши не оттянешь).


                      1. alexey_melezhik
                        03.06.2016 20:28

                        Мне нравится ваш ход мыслей :) Отчасти смотрите мой ответ MaverickCGRey по поводу образа с душком. Но вот что еще можно добавить:


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


                        • у такого подхода все же есть ограничение — наследование дистрибутива OS ( в самом базовом имидже ), в то время как Sparrow сценарии могут быть кроссплатформены ( а если завтра на будет нужен Debian? :)))) — все это выглядит слегка умозрительными, но об этом нельзя забывать


                        • но главное конечно не это. А то, что Sparrow не противоречит указанной вами архитектуре — еще раз повторюсь — никто не мешает разбивать очередной имидж в вашей иерархии на логические, более мелкие слои и настраивать их через Sparrow плагины ...

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

                        еще раз — разница это — возможность (простого) повторного использования плагина


                        вот вам кровь из носу нужно засунуть все приложение в единственный контейнер, начальник приказал

                        такое бывает часто ;))


                        1. alexkunin
                          03.06.2016 21:44

                          Окей, мы выяснили предполагаемую точку применения Спарроу. Допустим, смена дистрибутива реальна (хотя кого трогает, какой там дистр в моем самодостаточном контейнере? но допустим начальник прочитал статью «убунту суксь, дебиан рулез», а также не впечатлился моими доводами о необходимом времени для перехода).

                          Хорошо, задача: настроить апач, усложняем — вместе с пхп (ну, как часть LAMP, например). В моем типичном продкашн-случае настройка апача сводится к таким шагам:

                          1. поставить пакет апача
                          2. поставить пакеты модулей апача
                          3. изменить или заменить главный конфиг апача
                          4. добавить несколько хостов, каждый со своим конфигом
                          5. изменить или заменить конфиги отдельных модулей апача (некоторые вообще не конфигурируются, а некоторые — очень даже, например evasive)
                          6. поставить пакет пхп
                          7. поставить пакеты модулей пхп
                          8. изменить или заменить главный конфиг пхп
                          9. изменить или заменить конфиги некоторых модулей пхп (включить xdebug, дать ему порты и режимы, указать сертификаты, что-то такое)
                          10. выполнить несколько команд, включающих модули апача, пхп, хосты

                          Раз уж речь пошла о повторном использовании, допустим, что есть другой проект с очень похожими требованиями, только там нужно (относительно списка выше):
                          1. убрать php5-mysql
                          2. добавить php5-odbc
                          3. другая настройка главного конфига апача (слушаем другой порт, добавляем IPv6, пробрасываем парочку реверс-прокси)
                          4. другая настройка xdebug</li

                          5. Если я правильно понимаю, в терминах Спарроу это будут два плагина: для апача и для пхп. Каким образом спарроу спасет меня от написания двух отдельных скриптов для разных систем, учитывая различия, приведенные выше? Каким образом мне переконфигурировать эти плагины для второго проекта? И почему мне не лучше взять ансибль, паппет, чиф?


                      1. MaverickCGRey
                        04.06.2016 06:01

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


                        1. alexkunin
                          04.06.2016 09:11

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

                          Вордпресс хочет иметь сразу и пхп, и апач, и еще и доступ к файловой системе для аплоада контента и обновления себя/плагинов. И еще хочет знать доменное имя (ну, сам он вроде бы и не хочет, но есть плагины, которые начинают бросать ворнинги, если не прописать базовый урл полностью). Все это вместе делает вордпресс довольно «скученным» (монолитный и слишком умный).

                          Так вот, в идеале хотелось бы все пхп приложение засунуть в контейнер с fastcgi-сервисом. Но вордпресс хочет апач — ему нужно замапить все на себя, плюс еще несколько правил в .htaccess.

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


                          1. MaverickCGRey
                            05.06.2016 09:36

                            После прочтения фразы, что у вас нет Docker на production, почувствовал себе виноватым, за все заданный мной вам вопросы…

                            Хотелось бы только добавить, что не стоит процессу внутри контейнера менять своё состояние. Контейнер умер и был поднят на другой машине… вот вам и привет всем настройкам и плагинам, которые вы ему наставили.


                            1. alexkunin
                              05.06.2016 10:51

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

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

                              Так вот, из-за того, что человек этот знает только вордпресс и фтп, наш продакшн деплоится с помощью «svn up», и я периодически делаю с продакшна «svn add && svn ci». Человека трогать нельзя, научить ничему нельзя, даже wp-config.php редактировать нельзя.

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


                              1. MaverickCGRey
                                05.06.2016 21:00
                                +1

                                Ищите новое место работы.
                                Если гора не идет к Магомету, то гора идет лесом.


                                1. alexey_melezhik
                                  05.06.2016 21:03

                                  друзья, вот какая многогранная тема получилась, этот докер :)))


                                1. alexkunin
                                  05.06.2016 23:23

                                  Почему?? Платят хорошо, а трудности… «мастер познается в ограничении» ;)


    1. kvaps
      03.06.2016 22:57

      Полностью поддержу,
      Не понимаю зачем пытаться все конфигурирование запихнуть в Dockerfile? — на мой взгляд это неправильно.
      Dockerfile — нужен непосредственно для создания самого образа и должен включать в себя такие операции как: скачивание исходников, сборка, установка необохожимых пакетов и зависимостей, добавление конфигов и вспомогательных скриптов, а так же для объявление volumes и портов, но не больше.
      Все конфигурирование должно выполняться уже при запуске конкретного контейнера, например, стартовым скриптом, который выполняет предварительную настройку(установку?) приложения, исходя из переданных пользователем переменных окружения, непосредственно перед запуском самого приложения.


      1. alexey_melezhik
        03.06.2016 23:12

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


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


        1. kvaps
          04.06.2016 02:10

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


          Про конфигурирование во время сборки образа, здесь вопрос скорее в принципах его построения. Вы предлагаете оперировать образами так же, как и контейнерами: каждый отдельно взятый случай и уже неизбежна пересборка образа.
          Это определенно имеет место быть когда у вас есть в этом необходимость, но если честно я так и не смог придумать такую необходимость, при которой нельзя было бы записать все инструкции в обычный Dockerfile.
          Повторюсь, я имею ввиду именно установку и сборку ПО, а не его конфигурирование. Под конфигурированием я имею ввиду такие операции, как например: сгенерировать SSL-сертификат, создать базу данных $DATABASE, создать пользователя $USER с паролем $PASSWORD в приложении и т.д.; так как эти операции никак нельзя учесть при создании образа и они должны определяться пользователем при запуске контейнера.


          Именно такой подход обеспечивает простое управление контейнерами и правильную работу внутренних механизмов --link в docker, а так же избавляет вас необходимости пересобирать образ для каждой нестандартной ситуации.
          Ведь будь вы пользователем, все что вам нужно, это указать значение нужного параметра при запуске контейнера.


          Кстати, насколько я понимаю Phusion в своем baseimage исполюзуют тот же подход, что и у вас.


          1. MaverickCGRey
            04.06.2016 21:03

            Парочка вопросов.

            1. Зачем генерировать сертификат? Можно ли его передать контейнеру снаружи?
            2. А где находятся файлы данных базы? В контейнере?
            3. Зачем создавать базу при старте контейнера? Почему нельзя подключиться к уже существующей и управляемой отдельно?


            1. kvaps
              05.06.2016 15:11

              1. Затем, что вы не можете сделать этого заранее. Вы не знаете ни доменного имени которое будет указанно только при запуске контейнера, и конечно же вы не хотите, что бы у всех кто запустит ваш образ были одинаковые ключи.
                Можно сделать и так чтобы можно было передать сертификат снаружи, все зависит только от вашей фантазии и функций которые желаете реализовать в вашем образе. :)


              2. Если это контейнер базы данных, то вся персистентная информация должна быть вынесена в data volume.
                желательно еще оставить возможность подключать внешнюю директорию на место этого volume (многие недолюбливают и недоверяют консепцию docker data volumes)


              3. Я лишь привел в пример те операции которые должны выполняться внутри контейнера, если это контейнер базы данных, вам нужно создать базу данных с определенным именем, пользователем и паролем, которые, опять же, передает пользователь в виде переменных окружения (взгляните на официальный образ mysql)
                Позже, контейнер вашего приложения при помощи --link получает эти переменные и себе, автоматически подключается к этой базе данных, создает таблицы, правит свои конфиги и наконец запускается (примерно так же устроен официальный образ wordpress, за исключением того, что таблицы он создает при начальной установке в браузере)


  1. alexey_melezhik
    03.06.2016 23:05

    Если я правильно понимаю, в терминах Спарроу это будут два плагина: для апача и для пхп.

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


    • base-packages — устанавливает базовый список системных пакетов ( в вашем случае rpm ) — apache, php — базовый значит заведомо требуемый в каждом вашем проекте


    • apache-config — настраивает головной конфиг апача — причем тип настройки можно указывать как параметр плагина — типа хочу такой конфиг или такой; устанавливает, настраивает дополнительные апачевские модули и конфиги хостов


    • php-modules — устанавливает, настраивает конфигурацию модулей php — тоже самое — тип настройки можно указывать как параметр плагина — типа хочу такой список модулей, с такими конфигами, или что-то другое, включение, выключение php5-odbc, php5-mysql можно задавать исходя из выбранного типа конфигурации

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


    Каким образом спарроу спасет меня от написания двух отдельных скриптов для разных систем, учитывая различия,

    таки да, в какой то момент ( когда уже нечего выделять в общее ) вы пишите два разных скрипта ( или там набора скриптов ) либо два разных Sparrow плагина, но вся разница в том, что в будущем когда в дизайне системе что-то поменяется ( а оно поменяется с шансами… ) проще выделить снова общие сущности или сделать рефакторинг системы, когда вы оперируете плагинами, а не просто наборами скриптов ( или inline прямо в Dockerfile ) разбросанными по разным проектам. Фактически удачно придуманная система плагинов дает вам больше возможностей делать полезные модификации системы в целом, а не мыслить только в терминах отдельных докер контейнеров или скриптов… Эта просто сущность более общего порядка, а это всегда лучше, чем просто набор скриптов…


    1. alexkunin
      04.06.2016 09:30

      Правильно ли я понимаю, что Спарроу-плагин надо бы написать на каждый модуль апача и пхп, а также на сам апач и пхп? В том смысле, что если я напишу плагин для установки апача с модулями A, B, C и D, то другому человеку, которому нужны модули B, C, D и E (а вот A не нужен), этот плагин не подойдет.

      Тогда вопросы:

      1. если я случайно или намеренно установлю и запущу плагин для php5-mysql, но до этого не запущу плагин для php5, то что получится? есть ли какакая-то проверка зависимостей плагинов друг от друга?
      2. позволяет ли спарроу редактировать конфиги? скажем, два разных плагина хотят что-то в самом php.ini поменять, т.е. нельзя заменить его полностью — мне самому писать «sed ...», или спарроу поможет? мелочь, знаете ли, но трудоемкая и error prone (как это перевести...)


      1. alexey_melezhik
        04.06.2016 09:54

        1. Можно сделать по-разному. Например один php, Apache модуль — отдельный плагин. Или же наоборот один плагин даёт на выбор устанавливать жестко заданные наборы php, апач модулей, или же третий вариант, есть плагин который принимает на вход ( как команд Лайн параметр или параметр плагина ) массив php, апач модулей для установки — этот вариант самый общий. Вобщем выбирать исходя из контекста задачи.

        Ответы на вопросы. В обратном порядке.


        1. Сам по себе Спароу как уже не раз говорилось предоставляет некий базовый API, но он больше связан с организацией плагинов, вся реализация конечных сценариев Спароу не касается, разработчик пишет их сам. Ответ такой придётся реализовывать самому. Или шаблонизатором, если конфиг собирается снуля, или редактированием по месту ( как вы предлагаете ). Понимаю на самом дела ваш кейс, сам часто с таким сталкиваюсь. Но опять таки же можно попробовать динамические, меняемые секции в общем кофиге ввиде либо параметров модулей ( downstream историй ), либо ввиде входных параметров отдельного плагина, который настраивает конфиг, это может помочь не идти путём sed патчинга.


        2. Хороший кейс. Сейчас такого понятия как зависимости плагинов друг от друга нет, однако смотрите идею с таск боксами — коллекциями плагинов — см. В документации по Спароу, отчасти решает данную проблему.



        1. alexkunin
          04.06.2016 12:03

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

          1. еще одна инфраструктура, набор команд, внешняя зависимость моего проекта
          2. частичная подмена репозитория сырцов: вместо того, чтобы вынести общие скрипты в мою репу, я выношу ее во внешнюю инфраструктуру
          3. частичная подмена пакетного репозитория: я бы написал «apt-get install -y apache2», а пишу… ну, не знаю что именно, но смысл такой же — установка пакета
          4. между моим докерфайлом и пакетным менеджером системы (а также конфиговой парадигмой дистрибутива) появляется прослойка, враппер, который не добавляет полезную функциональность вроде редактирования конфигов, а просто заставляет учить новый синтаксис
          5. зависимость плагинов от систем, от которых они абстрагируют пользователя; например, если в дистре разделят какой-нибудь bundled module (в 14.04 поставлялся вмемте с php, а в 16.04 в отдельном пакете), то спарроу плагин должен быть обновлен и поддерживать обе системы — сильно усложняется внутренняя логика, особенно если плагин поддерживает десяток популярных дистров, в каждом по 2-3 популярные версии

          На сколько я понял, основная идея — из императивного «apt-get install {package}» (завязано на конкретный дистр и пакетный менеджер) вы хотите получить декларативное «нужен {component}». Но пока получается, что из довольно простой задачи (под конкретный дистр) делается довольно сложная задача (под все дистры, с разными опциями).

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

          Также, мало кому интересны все дистры сразу. Ладно, перешли на слакварь с дебиана. И все! Мне больше не нужно поддеживать слакваревскую часть, это не мой проект и не моя работа (а начальнику и подавно не нужны мои лишние рабочие часы), и даже если я такой добрый опенсорсщик, то мне придется где-то ставить уже не нужный дистр, проверять на нем, и т.д, или просто забросить уже неинтересную часть. И получится, что разные дистры будут иметь по-разному «свежую» поддержку. Это решается, просто толщина прослойки спарроу (и полезность) не сравнима с реальной пользой.

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

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

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


          1. alexey_melezhik
            04.06.2016 16:03

            ответил отдельным комментом тут :)


  1. MaverickCGRey
    04.06.2016 06:17

    Товарищи, а позвольте уточнить, как вы используете упомянутые supervisor'ы?

    1. «Я подключаюсь к контейнеру по ssh или через Docker CLI и запускаю клиент супервизора для выяснения ситуации с сервером.»
    2. «Супервизор сам открывает порт и выставляет свою web-морду, на которой я вижу что происходит с сервером.»
    3. «Супервизор экспортирует показатели сторонней системе (через файл или сетевое соединение), а я использую эту систему для автоматического мониторинга.»

    Опишите свой случай, пожалуйста, если я промазал.


    1. alexkunin
      04.06.2016 09:36

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

      Я говорил о демоне supervisord, которому можно указать «запусти вот эту команду, пожалуйста, а когда умрет — запусти еще раз, и так до бесконечности». Командами в моем случае были php-скрипты, которые запускались, коннектились к beanstalkd, ждали задачу из очереди, выполняли, завершали работу. После завершения работы супервизор запускает команду заново.


      1. MaverickCGRey
        05.06.2016 04:01

        Правильно ли я понял, что это некая особенность php мира, так реализовывать идею publish/subscribe? Ничего против не имею, просто не знаком с таким подходом. Как я понимаю, это некое подобие амазоновских ? — https://aws.amazon.com/lambda/

        А как вы или другая система снаружи узнает, что у такого контейнера все нормально? Как вы его мониторите?


        1. alexkunin
          05.06.2016 04:28

          Нет, это особенность, пришедшая мне в голову. :)) Впрочем, разве оно не так работает? Я имею в виду очереди вообще (beanstalkd в частности). Воркеров можно скалировать, переносить на другие сервера и т.д.

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


          1. MaverickCGRey
            05.06.2016 09:23

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

            А если у вас больше одного контейнера с таким «воркерами» и один из них «встал колом», но остальные работают. Как глядя на движущуюся очередь вы понимаете, что один контейнер «отлынивает»? В вашем случае «отряд не заметит потери бойца».

            Не буду больше ковырять. Как я вижу, для вас это все в самом начале и у вас у самого больше вопросов, чем ответов. Спасибо.


            1. alexkunin
              05.06.2016 11:03

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

              Да, а один из воркеров — это отдельная система за 3-мя файрволами (без дураков: я захожу по RDP к посреднику, который заходит по RDP на секретный сервер, и там у меня из внешнего мира открыт один хост и его 443-й порт, на который я замапил SVN и свой API для доступа к beanstalkd), стучится, забирает данные, добавляет в секретную базу данных, создает секретный ордер, и отписывается, получилось ли. Один ордер генерируется секунд от 10, и это не всегда получается. Раз в сутки эти неполучившиеся опять в очередь становятся, только счетчик попыток уменьшается, и когда их не осталось, больше ничего не делается. В админке на каждый ордер есть строчка в таблице (красненьким — фейлы) и лог (на сами операции с очередью — добавлен тогда-то, в процессе, получился, зафейлился, а также лог с секретного сервера аттачем).

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


            1. alexkunin
              05.06.2016 11:08

              обычно, значительно затратен, чем создание нового экземпляра такого обработчика.
              Кстати, я запуск процесса сделал еще и потому, что «PHP не предназначен для долгого выполнения». Я сам еще не проверял, миф это или таки проблемы (скорее проблемы, так как мы сидим на ветке 5.4, и пока я не вижу той кривой козы, на которой подъехать с вопросом об апгрейде). Просто сделал так, чтобы работал в режиме, близком к вебсерверу. Может быть, перестраховался. Смотрю в сторону поиграться с микросервисами, наверное придется делать все тоньше, т.е. как вы и говорите — на уровне создания экземпляра класса, а не запуска скрипта.

              И вообще, спасибо за ваши вопросы, помогают. :)


    1. kvaps
      04.06.2016 11:46

      Supervisord обычно используется в качестве инит системы для запуска и контроля ваших сервисов.
      В официальной документации docker предлагается тогда, когда существует необходимость использовать несколько сервисов одновременно в одном образе.
      Так же помогает решить проблему с PID 1 zombie reaping (если она есть).


      1. alexkunin
        04.06.2016 12:07

        Именно так его и использую, проверенное временем и рекомендованное решение вместо «скриптик на коленке». Жаль только, что это пачка питоновских скриптов (и зависимость от питона), а не Go-бинарь на пару мегабайт. Пришлось ломать кое-какие свои принципы. :(


      1. MaverickCGRey
        05.06.2016 04:10

        1. Мне казалось, что концепция «один контейнер — один процесс» уже устоялась и принята как генеральное направление. Зачем мне контролировать сервис внутри контейнера? Пусть сгинет вместе с контейнером и тот кто отвечает за контейнеры, поднимет новую копию. Этот надзиратель все равное есть, дак зачем мне усложнять runtime нутро контейнера?

        2. Правильно ли я понял, что «PID 1 zombie reaping» результат особенностей Docker ранних версий и на данный момент она не актуальна?


        1. kvaps
          05.06.2016 14:39

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


          2. Насколько я понял, здесь проблема не сколько в Docker, а сколько в отсутствии нормального init'а. Проблема остается если вы запускаете программу которая плодит кучу процессов. При отсутствии нормального inita, может возникнуть данная ситуация.


          1. MaverickCGRey
            05.06.2016 22:33

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

            Для меня процесс — это запущенный в кластере контейнер. И обычно, одно приложение — это не один контейнер, а множество.
            В моем мире ситуация запуска в контейнере одного процесса другим возможна. Например, когда python скрипт запускает JVM, но это исключение. Обычно, запускается одиночный процесс.

            Для меня, сron — внешняя система, которая просит надзирателя над кластером запустить контейнеры.

            Процесс помогающий работать с логами основного контейнера — это ещё один контейнер, запущенный в паре с основным. По типу sidecar описанному тут http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html


            1. kvaps
              05.06.2016 22:59

              Когда вы сами пишите приложение, то да, учесть все это и сделать по правильному намного проще, чем тогда когда вы докеризируете уже написанное кем-то приложение, особенно если оно очень крупное (комбайн), состоящий из множества связанных между ссобой сервисов. Вот вам в качестве примера: gitlab, kolab, или и тот же самый postfix, который без rsyslog логи писать не будет.
              Я не говорю что это правильно, я рассказал для чего ипользуется.


              1. MaverickCGRey
                07.06.2016 02:32

                Согласен. Текущее состояние большинства приложений не позволяет назвать их «cloud native» именно из-за таких вот жёстких зависимостей.
                Ну ничего. Засохнет и отомрёт. Не до конца, конечно. Ведь и сейчас mainframe'ы есть. Но mainstream течь другом русле.


  1. alexey_melezhik
    04.06.2016 15:58

    @alexkunin спасибо что так много написали. не хочется отвечать по всем пунктам — будет слишком много деталей и мелочей, а кажется важно понять принципиальные вещи. :))


    Вот как я вижу идеологию Sparrow


    • система плагинов решающая различные задачи автоматизации


    • Sparrow это не силвер балет он сам по себе не решает из коробки ВСЕ задачи — это некая инфраструктура упрощающая и поощряющая повторное использование кода то бишь скриптов в задачах автоматизации, но внимание — сами эти задачи решают конкретные плагины, которые пишут конкретные люди ( хорошо или плохо это уже другой вопрос )


    • вот что дает Sparrow из коробки


    • возможность написать свой полезный скрипт и сделать его публичным ( или условно публичным — приватным, — см. док-ю по Sparrow — приватные и публичные плагины ) — что бы кто-то другой смог его повторно использовать ( не важно в рамках вашей же компании, проекта или в обще)


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


    • В случае с публичными плагинами немаловажно, что есть web интерфейс к репозитарию таких плагинов — https://sparrowhub.org позволяющий поискать нужные плагина и посмотреть дополнительную полезную информацию, связанную с плагином — авторство, документация, ссылки на исходники и т.д.


    • Все это поощряет и упрощает повторное использования уже кем-то написанных и протестированных скриптов-плагинов


    • В добавок к этому разработчику плагинов из коробки обеспечивается API по конфигурации плагинов — другими словами вам не надо писать самому то, что скорее всего вам потребуется — а именно обработку входных параметров своих скриптов. Это API реализован для трех форматов данных — параметры командной строки, YAML, Config::General.


    • Sparrow поддерживает модульность — когда у вас есть группа сценариев, которые могу вызваться в определенный последовательности или когда один сценарий вызывает другой с передачей параметров, опять таки же вам не нужно это писать с нуля, я называю это модульностью в том смысле что сценарий модуля в рамках одного плагина — могут вызываться больше чем один раз с различными параметрами. Подробнее об этом на страницах док-и (upstream, downstream strories)


    • Sparrow предоставляет встроенную систему тестирования работы сценариев Outthentic::DSL с генерацией отчетов в переносимом на многие системы формате TAP


    • И наконец все эти фичи не зависят от того, на каком из трех языков вы пишите сценарий — Perl, Ruby, Bash


    • Это те ценности, которые вы получаете из коробки, когда вы пишите свой скрипт не просто на Bash или Perl или Ruby, а в контексте Sparrow плагина, по-моему немало

    Далее:


    • порог вхождения в Sparrow архитектуру — не такой уж большой, т.к. повторюсь еще раз и еще раз — Sparrow не навязывает своего DSL или нового языка разработки — вы всегда пишите на одном из трех языков — Bash, Perl или Ruby


    • Sparrow не является никакой заменой пакетных менеджеров, да это врэпер, но с таким же успехом скрипт внутри которого вы написали что-то типа yum install apache тоже будет врэпером


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


    1. alexkunin
      04.06.2016 16:51

      порог вхождения в Sparrow архитектуру — не такой уж большой
      Он огромен, уверяю вас — как пользователь разработчику говорю.
      типа yum install apache тоже будет врэпером
      Нет, это будет просто скрипт — перечисление команд, которые я бы набрал в командной строке, заглядывая в «методичку».

      В общем, чего не хватает, так это «смотрите как это сложно делается без спарроу, и как просто с ним» — эдакого развернутого примера.

      Статья выше таким примером не является, т.к.
      regexp: ruby version: ruby 2\.3
      install-ruby-ok
      — это «тарабарщина», не ясно, что есть команда, что данные, и т.д. Вы вроде бы опираетесь на YAML и т.д., но при этом используете что-то самопальное (или я что-то не понял). Так же в ваших плагинах встречаются .ini-файлы, только вот они не .ini, а что-то другое (похоже, вместо "=" разделителем является пробел, но это мои домыслы).

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

      Вы много говорите о возможностях повторного использования, но не демонстрируете их. Заверните, например, инсталляцию вордпресса — с мускулом на борту, или с указанием внешнего мускула, с апачем — на борту или внешним, и т.д. И сравните (скринкастом, например) ручной и автоматизированный процесс. Добавьте «щепотку специй» — укажите хитрый параметр своему плагину, который сделает «бум!» — что-то офигенное, на что в ручном режиме пришлось бы набрать десяток других команд (не могу придумать, что — но что-то из «сложного и тонкого конфигурирования», о котором писалось выше).

      Короче, «продайте» ваш скрипт. Докер продался сразу, я побежал пробовать, восхищаться, обзвонил всех знакомых. Гит продался сразу — на свн смотрю теперь как на необходимое зло (а три года назад мне пришлось работать с цвс — я чуть проект не бросил с психу). И т.д.: очевидные, всеобъемлющие, вкуснейшие преимущества. Пока я вижу что-то вроде маркетинговой патоки, примерно как микрософт поясняет преимущества легальной копии винды.


      1. alexey_melezhik
        04.06.2016 17:55

        • Целью статьи не было описание API sparrow, поэтому отдельные моменты без чтения документации или ознакомления с основами, будет сложно понять, я об этом предупредил вначале )) это насчёт "тарабарщины".


        • не вижу никакого отличия от просто скрипта, который пишется кем-то, от просто скрипта который опять таки же пишется кем-то и затем "упаковывается" в плагин. И там и и там скрипт -) и там и там yum install или что-то аналогичное


        • возможности повторно использования. Согласен с вашей ремаркой, но опять таки же нельзя в одной статье рассказать все -)


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


        • да и за примерами — сходите на спароухаб, там конечно не "космические" Корабли, но позволяют понять подход в Спароу методологии, да и ещё статьи на blogs.perl.org — http://blogs.perl.org/mt/mt-search.fcgi?limit=20&search=Sparrow очень полезны в этом плане


        1. alexkunin
          04.06.2016 18:15

          Целью статьи не было описание API sparrow, поэтому отдельные моменты без чтения документации или ознакомления с основами, будет сложно понять, я об этом предупредил вначале )) это насчёт «тарабарщины».
          О том и речь: простая вроде бы вещь требует вдумчивого чтения документации, кривая обучения круче некуда. Вопрос об использовании популярных форматов остается открытым: вы расплодили сущности вместо того, чтобы воспользоваться уже существующими — и это в проекте, который призван уменьшить количество сущностей и дублирование кода!
          не вижу никакого отличия от просто скрипта, который пишется кем-то, от просто скрипта который опять таки же пишется кем-то и затем «упаковывается» в плагин. И там и и там скрипт -) и там и там yum install или что-то аналогичное
          Я нечетко выразился. Есть потяние «скрипт» как просто список команд: нет ветвлений, нет проверок, примерно как макрос, записанный с клавиатуры. Докерфайл — прекрасный пример скрипта. Да, нужно было другое слово использовать, но пока не могу придумать подходящее устоявшееся.
          но опять таки же нельзя в одной статье рассказать все -)
          Вот и расскажите про _мясо_, про главное, про самое интересное и захватывающее. И засуньте это на главную страницу вашего проекта. Если не уверены, что именно интересно, напишите две перпендикулярные статьи, потом посмотрите на количество просмотров-лайков. Трудоемко, конечно же.
          сходите на спароухаб
          Оттуда и узнал про ini который не ini. И нашел тривиальные скрипты в 1-2 строки, завернутые в плагины с помощью нескольких дополнительных файлов. Кстати, там довольно мало плагинов (как я понял), но нет списка — только поиск. Я попробовал "-" — нашлось с десяток, попробовал "." — ничего не нашлось (баг?). А до этого я ввел mysql — 0 результатов, apache — тоже 0, php — 1 результат не ясно об чем (какой-то ваш внутренний проект).

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

          И еще раз: я просто не знаю, в каком месте вписать спарроу в мой воркфлоу. Или в каком месте вписать свой проект в воркфлоу спарроу, если таковой существует. Проведите опрос: что бы люди хотели бы увидеть? Увидите, скажем, 10 вариантов настройки апача, сделайте плагин, если будет удачный — реклама проекту, благодарность людей.


        1. alexey_melezhik
          04.06.2016 18:17

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

          Да тут есть нестыковка по названию, дело в том что в более раних версиях формат был именно ini style, затем я перешёл на Config::General, а затем добавил поддержку yaml. Но название самих файлов осталось старым suite.ini, что согласен вводит в заблуждение, но опять таки же в документации все расписано. Да и в этой статьи используется формат кончиков Config:: General ...


          1. alexkunin
            04.06.2016 20:36

            Знаете, как человек, успешно забывший перл примерно 10 лет назад вместе с последним проектом, я не в курсе, что такое Config::General. Думаю, башисты и рубисты тоже не очень вкурсе, а это 66% вашей потенциальной аудитории (грубо, конечно же, может и меньше, а может и больше). Такие вот нестыковки в молодом проекте «портят» ему карму, а также усложняют овладевание. Если на кнопке написано «спирт», а при нажатии получается «чай», то пусть хоть сто раз в доках расписано, люди будут недовольны.

            Но это, конечно же, одна из меньших проблем проекта.


            1. alexey_melezhik
              04.06.2016 21:58

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

              Я не сказал, что не понравилось ))) Можно и написать будет, почему нет? )))


              Проведите опрос: что бы люди хотели бы увидеть? Увидите, скажем, 10 вариантов настройки апача, сделайте плагин, если будет удачный — реклама проекту, благодарность людей.

              Да я как бы и не против. Кстати есть проекты, которые для которых плагины существую, и вроде как людям нравится


              И нашел тривиальные скрипты в 1-2 строки, завернутые в плагины с помощью нескольких дополнительных файлов.

              Не совсем так. Есть действительно простые вещи ( не вижу в этом ничего зазорного, если на данном этапе 1-2 комманды — это все что нужно, то и окей, если кому-то нужно что-то еще — есть github можно создать issues или pull request сделать, законтрибутить в плагин ), но например посмотрите loggod или stale-proc-check или gtiprep ...




              @alexkunin в целом я вас понял, спасибо за отзыв, и за ценные советы, будем работать ))))


              1. alexkunin
                04.06.2016 22:35

                loggod не ищется, stale-proc-check — половину кода можно выбросить, если вместо etime использовать etimes (и можно еще как перл-хакер в три строки уместить все, да и вообще перл зачем тут), gtiprep не ищется, но нашелся gitprep — да, пример посолидней (только подтяние свой баш, пожалуйста), похоже на рабочее решение. Правда, до этого я не в курсе был, что такое gitprep, пример получился сферический в вакууме (для меня), но, видимо, вы решали свою реальную задачу.


                1. alexey_melezhik
                  04.06.2016 22:44

                  • Извиняюсь отпечатался, logdog
                  • да GitPrep, тоже отпечатался
                  • stale-proc-check, сейчас могу за давностью времени ошибаться, но etimes не со всех линуксах есть, писал на perl, потому что просто было удобнее, попробуйте на чистом bash манипулировать с датами ввиде 1 weeks, 2 days, 4 minutes. В перле это уже все есть, через модуль DateTime


                  1. alexkunin
                    04.06.2016 23:23

                    Ну, так и sudo с curl не везде есть, вы же не проверяете их наличие, хотя это зависимости. Кстати, где-то внутри кода забить sudo много раз не ок, у человека может быть настроен пароль на каждый суду-чих, лучше бы перед sparrow указывать sudo.

                    И на каких линуксах нету etimes? И на какие плагин рассчитан? А то именно в этом не указано, хотя в других указано.

                    На счет дат все верно, только зачем такой вывод было делать — ведь если его перенаправить на вход другой программы, то ей нужно будет конкретно потрудиться чтобы распарзить. Уж хотя бы в формате etime выдавали бы — d-hh:mm:ss.


                  1. alexkunin
                    04.06.2016 23:48

                    Кстати, «cmd» тоже не везде поддерживается, к примеру OSX хочет видеть «comm» (линукс тоже понимает comm). А еще есть «lstart», формат которого можно таким вот образом в таймстемп перевести:

                    date -d "$DATE" +%s
                    


                    1. alexey_melezhik
                      05.06.2016 08:47

                      Спасибо! Буду иметь ввиду .


              1. alexkunin
                04.06.2016 22:56

                И еще одно «фе» касательно юзабилити (вы, конечно, не будете ничего менять уже, но тем не менее).

                Сейчас формат команды такой:

                sparrow plg run gitprep --param action=install
                т.е.:
                sparrow {global noun} {global verb} {plugin name} --{global parameter} {global parameter name=value}

                А можно бы:
                sparrow {plugin name} {plugin specific verb} {--} --{plugin parameter}={value}

                Т.е. после явного или неявного "--" все интепретируется как параметры плагину (а все параметры до "--" — это к спарроу), в виде ки-вэлью, произвольное количество. Так же не нужно делать список обязательных действий, пусть плагины сами их определяют. Ну, и «plg» — он у вас везде и так, зачем повторять.

                Конкретные примеры для наглядности. Сейчас:
                sparrow plg run gitprep --param action=install
                sparrow plg run gitprep --param action=start --param start_mode=foreground
                sparrow plg run gitprep --param action=stop

                Могло бы быть:
                sparrow gitprep install
                sparrow gitprep start --start_mode=foreground (почему не просто mode, кстати, раз уж action указан)
                sparrow gitprep stop