• Linux=Terminal?
    +1
    Для тех, кто не хочет читать статью целиком:

    Линукс, терминал, курсы!
    apt-get install -y xvfb

    Ну купи
    docker build .

    Ну почти девопс уже ж… ну купи,
    ну ннада
  • Yaml vs. Json — что круче?
    +2
    Вот ещё: noyaml.com
  • Wikimedia переезжает с Gerrit на GitLab
    +1
    Думаю минусуют за грубость, а не за смысл
  • Wikimedia переезжает с Gerrit на GitLab
    0
    Ну это я ради объективности. Есть в гитлабе и хорошие стороны. Вон, дебиан же поднял себе salsa. Наверняка они много думали перед таким поворотом.

    Меня от геррита останавливает только одно — кроме дженкинса не могу прикрутить никакого вменяемого ci (наподобии gitlab-ci или github actions). Кто бы подсказал как это сделать — уже бы ушёл на него.
  • Wikimedia переезжает с Gerrit на GitLab
    +1
    Gerrit так и задумывался, чтоб работать над коммитами, а не над ветками.
    Каждый коммит — логически законченное изменение.
    Видеть в истории 50 коммитов «хождения по граблям» и потом «кусок говна, который ноканец-то заработал merged to master» — не очень приятное зрелище.
    Увидеть 3 patchset-а в стиле «Add feature 1», «Add test for feature 1», «Update docs» — намного приятнее и проще ревьюить. У вас есть пачт или серия патчей. Всё.

    Чего не хватает в gitlab ce:
    1. Approves — плати
    2. Auto Reviewers — если и есть — скорее всего плати
    3. Проверка каждого коммита, а не ветки. На вопрос «зачем?» оставлю время подумать
    4. Скорость ui — gitlab тормозит. Ну вот реально тормозит. Просто мы отвыкли уже от по-настоящему быстрых вещей
    5. Сделал ревью, оставил комментарии. Пришёл новый пуш и все комменты outdated. Как было и как стало — иди ищи, открывай старое, вспоминай где оставил коммент, открывай новое, смотри как стало. Может доработают
    6. Review имён файлов как?
    7. Review commit message как?
    8. Хуки и валидация commit-ов — плати/получи админские права на инстанс.

    Но тут как сравнивать. Gitlab как code review system пока никакой.
    Gerrit как project management system — тоже никакой.
  • В защиту swap'а [в Linux]: распространенные заблуждения
    0
    Мониторинг вас не спасёт. Картинка будет такая:
    1. всё хорошо, ни что не предвещало беды
    2. всё хорошо, ни что не предвещало беды
    3. всё хорошо, ни что не предвещало беды
    4. Мы упали, ошибки, данные потеряны
    5. всё хорошо, ни что не предвещало беды
    6. всё хорошо, ни что не предвещало беды
  • Новое поколение разработчиков. Чем они отличаются и почему это нормально
    +3
    Имею определённый опыт и взрастил уже много людей с джуна до уверенных сеньоров. Конечно, это их заслуга, кто хочешь/может — растёт.

    Но вот что я вижу постоянно: человек сначала джун, уже через 3 месяца научился тыкать кнопку и хочет быть мидлом, а через полгода уже «ну когда сеньор и ЗП в $2500?». А вон Вася из конторы ХХХ умеет меньше, а уже сеньор и прочие радости.

    И это большая проблема. Банально, запутались в SSL/TLS сертификатах, какой там куда? Где CA, где private key, куда dhparam класть и работа встаёт на 2 дня из-за глупостей и отсутствия базовых знаний. Научились в кубике ямл писать без понимая и любое нестандартное поведение — застряли на неделю.

    Как это всё получается? Прочитал очень хороший пример про абстракции. Вот у нас есть железо, машинный код, над ним язык более высокого уровня, над ним ещё более высокого, над ним библиотека, над ней фреймворк, над фреймворком ещё IDE. Абстракции имеют свойство «течь», когда в 15% случаев поведение абстракции неожиданно.
    // псевдокод
    int main() {
      int fac = 1;
      for (int i=1;i<=10000000; i++) {
        fac = fac * i;
      }
      std::cout << fac; // почему не работает?
    }
    


    Имеем вероятность того, что написанная система будет работать 0.85^N (если 15% течёт, конечно), где N — количество абстракций. Прилага в кубике, которая ранает докер, который крутится на хосте, который ранает непосредственно бинарник, который на фреймворке, в котором куча библиотек, которые используют язык высокого уровня, которые интепретируются… ну да хватит. 0.85^8 = 0.2724905250390625 — вероятность, что будет работать без проблем.

    И тут начинают сыпаться «сеньоры», которые просто проскочили базу. Всё меньше и меньше людей заглядывают под капот. А надо хотя бы на 2-3 абстракции вниз разобрать. А это в школах часто пропускается. И опыт показывает, что те, кто лазил под капот — быстрее и лучше понимают и решают проблемы.

    Мне представляется кардио-хирург, который сделал надрез и дальше по-быстрому в инете гуглит, как там дальше.
    Или зачем админу знать как на баше вывести предпоследнюю строчку, если можно на SO нагуглить?
  • Коммерциализация доработок свободного ПО под Copyleft лицензиями
    0
    А мне вот интересно, на сколько легальна «схема», которую я встречаю:
    1. Делаем некий тул bicycle
    2. Открываем это под opensource свободно
    3. Собираем коммьюнити, развиваем проект
    4. Пользуемся балагами сервисов, который предоставляют опенсорсным проектам плюшки бесплатно (ci/bugtracker/wiki/tools/etc)
    5. Покупаем торговую марку «My Bicycle» и вешаем на бинарники коммерческую лицензию.


    Как результат: исходники вот они, все «белые и пушистые». Но как только ты эти исходники собрал — бинарник под лицензией. И тут тонкая грань, что сам по себе бинарник может и не быть под лицензией, но его имя — трейдмарк и просто так пользоваться этим нельзя. Толку от исходников, если на выходе «тыква»? Форкать и бегать sed-ом…
  • Ежедневная работа с Git
    0
    Я бы начал с того, что убрал гит из уравнения. У вас должен быть некий проект. Он живёт где-то в каталоге и как-то организован и понятен. Если внутри него есть какие-то фичи (которые являются полностью самостоятельными) — то они то же как-то лежат в этих папках. Всё. Если у вас 10 проектов — значит 10.

    Теперь добавляем гит. Это как «вселенная проекта» — каждый коммит — состояние вселенное на определённый момент времени. Вы можете двигаться вперёд и назад по времени. Фича бранчи в данном случае — альтернативное состояние вселенной, которое не влияет на основную.

    Когда большая команда разрабатывает проект, фича бранч создаётся, чтобы разрабатывать и проверять новую фичу, не мешая проекту. Если фича не стабильна, ломает всё или не совместима — можно продолжать её разрабатывать, в то время как основная ветка (часто master) выходит в прод. Предполагается, что каждая такая ветка рана или поздно будет «влита» в мастер. Т.е. в мастере будут все фичи, который условно стабильны.
  • Как не положить тысячи серверов с помощью системы централизованного управления конфигурацией на примере CFEngine
    0
    В действительности ансибл вообще не декларативный.
    Пример выше про «state=restarted» — это раз.
    И любое действие — это императивный вызов, он просто с идемпотентностью в лучшем случае: поставь если не стоит, создай если нету и т.д. На ансибле ты не описываешь конечное состояние, ты пишешь «сделай а, сделай б»
    И вот декларативный пример, который, конечно же не будет работать:
    # псевдо-код
    - service: httpd
      state: started
    - package: httpd
      state: installed
    
  • Исповедь docker хейтера
    +3
    Тем, что чел явно хотел делать chmod ;)
  • Исповедь docker хейтера
    +1
    > Допустим под 20
    сколько РАЗЛИЧНЫХ контейнеров ранается в проекте. Возможно, у вас действительно 20. Но если у вас кластер эластика на 15 машин — считайте это за 1.

    >унифицированные интерфейсы конфигурирования
    нет. Переменные окружения? У всех всё по-разному, а некоторые аппы, пока файл не положишь — не заработают. Либо приложение можно удобно конфигурировать, либо нет. Докер тут никак не помогает. И если завтра дедлайн, а конфигурить через файл — будешь монтировать файл.

    >Не зависит особо от докера
    О том и моя мысль, что плюсы, которые приписывают докеру, вовсе не его

    > Да, можно понаписать башскриптов
    Не так. «нужно понаписать пачку башскриптов». Entrypoint более-менее непростого контейнера видели? Init перед entrypoint-ом и прочее весёлости. там много скриптов получается. Благо, это не всегда плохо.

    > Грубо, 49 запущенных на хосте nginx слушают порт 8080 и только один слушает 80
    Это тоже не про докер.
  • Исповедь docker хейтера
    +1
    > они начинают больше думать головой
    они начинают больше копипастить со stackoverflow в стиле
    apt-get install 200 пакетов которые я хз зачем

    или
    chmod 777 -R /usr # потому что без этого, почему-то не работает


    И мой любимчик:
    chown 775 /home/app
  • Исповедь docker хейтера
    +8
    Внесу свои 6 копеек.
    Я тоже недолюбливаю докер, хотя, начал использовать его до того, как это стало мейнстримом.
    И мои мысли о тех преимуществах, про которые рассказывают следующие:
    1. Безопасность — разработчику плевать, это не то, ради чего он рад пользоваться докером. admin/admin глубоко в коде и прочие радости. Пока разраба не пнут — не пофиксит
    2. Изоляция процессов — посмотрите на свой проект, сколько там контейнеров? 5? nginx, java, redis, postgres, logstash? Запусти это всё просто на хосте и ок. Что тут изолировать? Другое дело, если вы — public ci cluster. Может быть.
    3. Удобство запуска — НЕТ. Да, выполнить docker run легко. Но прилага на дефолтах. Только «на посмотреть». Когда надо сконфигурить — поехали тонна переменных окружений, монтирование папок, конфиг-файлов и т.д. А entry-points под это дело писать на 2000 строк — то ещё удовольствие.
    4. Сетка — стало только сложнее. А когда речь идёт о траблшуте, почему порт из контейнера внутри hyper-v на хост систему не пробросился — почему-то теряются даже сеньоры.

    И вот мы подобрались к тому, из-за чего контейнеры стали популярны:
    5. Запаковать all-in-one. Современный разработчик — это модный чувак, который сидит под вендой, тыкает пальцем в кнопочку в ide, нихрена не понимает как устроена его ОС, не умеет в линукс, не умеет упаковывать и распространять дистрибутив своей же программы (tar.gz/npm/deb/rpm/gem/whatever). Но при этом разрабатывает, конечно-же, под линукс. И как же ему бедненькому всё что он локально сделал запустить? Правильно, используя stack overflow наустанавливать не пойми чего, скопировать всё подряд и через 30 баш скриптов запустить без особого понимания в докере. Зато работает. А потом на прод.
    Docker — это современная package management система.

    Ну и, пожалуй, есть ещё один удобный пункт — который близок к 5ому:
    6. создание окружения для сборки. Собрал себе в контейнере всё, что нужно, компиляторы, тулы, и т.д. — и собирай себе на здоровье. Кстати, это же можно было делать и в chroot, но да — docker удобнее будет.

    Альтернативы: разобраться в пакетной системе. Например, deb трекает каждый файл при установке и гарантировано удалит это за собой во время удаления. Есть жизненный цикл пакета — pre/post-install/rm, pre/post-configure и т.д.

    Однако, текущие пакетные системы тоже имеет проблемы, например, нельзя или очень сложно иметь сразу несколько версий пакетов в системе. И тут на сцену выходят следующие ребята, которые решают и это: nix, guix, flatpack, snap, chef habitat.
  • Как генерировать осмысленные коммиты. Применяем стандарт Conventional Commits
    +2
    Предположу, что так сделано из-за идеи в гите с переписыванием истории коммитов. В английском варианте:
    If I (merge|cherry-pick|rebase|use|...) this commit it will (commit message):
    If I use this commit it will «Add logout button to home page».

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

    По-русски, наверное, стоит перефразирвать, т.к. слова меняются из-за склонения и времени.
  • Как киту съесть Java-приложение и не подавиться
    0
    И ещё чего-нибудь из этого списка (конечно, не всем нужен какой-нибудь gtk):
    Скрытый текст
    — libasound2 (>= 1.0.16)
    — libatk1.0-0 (>= 1.12.4)
    — libc6 (>= 2.7)
    — libcairo2 (>= 1.2.4)
    — libfontconfig1 (>= 2.11)
    — libfreetype6 (>= 2.2.1)
    — libgcc1 (>= 1:4.2)
    — libgdk-pixbuf2.0-0 (>= 2.22.0)
    — libglib2.0-0 (>= 2.35.9)
    — libgtk2.0-0 (>= 2.24.0)
    — libpango-1.0-0 (>= 1.22.0)
    — libpangocairo-1.0-0 (>= 1.14.0)
    — libpangoft2-1.0-0 (>= 1.14.0)
    — libstdc++6 (>= 4.1.1)
    — libx11-6
    — libxext6
    — libxi6
    — libxml2 (>= 2.7.4)
    — libxrender1
    — libxslt1.1 (>= 1.1.25)
    — libxtst6
    — libxxf86vm1
  • Как киту съесть Java-приложение и не подавиться
    0
    Я смотрел из статьи:
    openjdk 8 db77212ffe05 13 days ago 737MB
    openjdk jre e956268fd4ed 13 days ago 538MB

    Alpine меньше, но не из-за того что «alpine vs debian», т.к. между ними разница в 95 мб
    Могу только осторожно предпложить, что не каждый java проект заведётся на этом alpine образе
  • Как киту съесть Java-приложение и не подавиться
    –1
    Да, из-за скачивания холодный старт может быть на 1-2 секунды дольше. Например, вместо 12 секунд будет 14.

    У самого есть такая проблема: оптимизировать по каплям, где всё просто и понятно, когда что-то и так работает нормально. Не смотреть в сторону того, что создаёт 90% проблем потому, что там сложнее и чуть менее понятнее.
  • Как киту съесть Java-приложение и не подавиться
    +2
    Level 1.
    Официальный openjdk приносит с собой 600 МБ (jre — 450 МБ).
    * Если на базе дебиана сделать — то итог 737 мб.
    * Если на базе алпайна — то 639 мб.
    Сильно выйграть не получиться. А это мы ещё апп внутрь не заливали.

    Сделать контейнер меньше всегда хочется и приветствуется. Но никогда не понимал попытку сэкономить на спичках.
    Как не читаешь на эту тему что-нибудь: так все работают в гуглах, фейсбуках, нетфликсах и у всех 10к+ машин и 100к+ контейнеров. Как дело доходит до практики — 3 сервера и 5 контейнеров :).
  • Как я использую git
    0
    Для стандартных действий — да, кнопку нажать быстрее. Для более менее нестандартных ситуаций — нет. И тут начинается: из gui это сделать вообще можно? Есть там такая фишка? А где? Сколько минут будете лазить пока найдёте?
    Use case:
    1. Вы что-то там себе в ветке fix-foo делали
    2. Потом переключились на dev и продолжили работу.
    3. А теперь вас попросили пушнуть ветку fix-foo только под нормальным именем, типа bug/proj-1567-fix-foo

    Из консоли это можно сделать одной командой и не будет путаницы в «понимании поведения интерфейса».
    В итоге бывает проще выучить 1 инструмент (git cli), чем несколько. Конечно, это не отменяет того, что GUI — удобная штука.

    Кстати, пункт 4: пушнуть ветку fix-foo без последнего коммита (потому, что там ерунда) — это всё ещё одна команда.

  • Установка и настройка MongoDB на Debian, а также ReplicaSet и пара других мелочей
    0
    Но мы должны изначально задать Primary


    Может, мы одно и тоже по-разному понимаем, но:
    1. Ничего вы не должны.
    2. Берём три сервера (будущая реплика). На любом делаем инициализацию.
    3. И можно сразу скормить весь конфиг, не делая rs.addWhatEver().
    4. Готово.
    Возможно, не стоит делать инициализацию на будущем арбитре. Я, чтобы наверняка работало, подключался только к тем серверам, которые могут стать мастером в будущем. Этого достаточно.
    У меня было так N серверов для master/slave + 1 сервер арбитер. Я подключался к первому попавшемуся из N и делал rs.conf, скармливая весь список. Реплика инициализируется и работает.
  • Установка и настройка MongoDB на Debian, а также ReplicaSet и пара других мелочей
    0
    Это для шардированного кластера.
    Сервера собираются в репликасет. Репликасеты собираются в общий кластер. Роутер — точка входа, балансер, прокся, вроде бы умел функции агрегации и возможно что-то от map reduce. Но тут боюсь соврать. Лучше почитать доки. Они реально неплохие. Можно потратить 6-8 часов и полностью разобраться что там у монги есть.
  • Установка и настройка MongoDB на Debian, а также ReplicaSet и пара других мелочей
    0
    Если у вас только репликасет. можете — заставит просто лить в мастер, а слэйвы скопируют всё.
    Можно указать replicaset connection string в виде: rsName://host1:port1,host2:port2… — тогда драйвер сам разберётся. Но мне так делать не приходилось. Я восстановление обычно в роутер произвожу. Опять же с шардированным кластером не всегда так можно.
  • Установка и настройка MongoDB на Debian, а также ReplicaSet и пара других мелочей
    0
    В монге мастера назначать не надо. После выхода из строя мастера происходит голосование и выбор нового мастера автоматически.

    multicast удобная штука, но не всегда доступен.
    unicast — заставит вас всё равно мейнтейнить список. в принципе для своего кластера сгенерил json, в котором описана топология.
    + есть ещё набор инструментов для развёртывания разных кластеров буквально кнопками, но он платный на сколько мне известно.

    Я бы сказал, что у монги с этим всё не так уж и плохо.
    Как выяснилось, у того же постгреса всё намного печальнее. Но там и типа базы другой, можно понять.
  • Continuous delivery с Travis CI и Ansible
    +1
    hello-world:
    git remote add prod ansible@2.2.2.2:/path/to/bare/repo
    git push prod master
    
    # ..  ну и post-receive hook который сделает checkout
    
  • Собираем Docker-образы для CI/CD быстро и удобно вместе с dapp (обзор и видео)
    +1
    Вот тогда-то и не нужно брать Chef.
    А то получается, что делаем «hello world», берём для этого инструмент энтерпрайз уровня и потом волосы <вставить_что_они_делают_при_упоминании_шефа>

    Но ближе к существу, мне действительно интересно, что не так с шефом, когда с ним начинаешь знакомиться. Что лично вам не понравилось?
  • Синхронизация ритма в музыкальных играх
    0
    Если в кратце, то никак :)

    В ритм играх (допускаю, что конкретно в Guitar Hero это может быть не точно так, как написал), как правило, есть аудиотрек и так называемый simfile — мета-файл в котором и описаны:
    • GAP (OFFSET) — задержка от начала аудиофайла до первой ноты. Авторы часто подгоняют до первой ноты после вступления
    • BPM — темп. Что очень важно, его надо считать очень точно, желательно 5-7 цифр после запятой
    • BPM Changes — обычно время=новый_темп, время=новый_темп и т.д.
    • Delay/Pause — остановки в треке. С нимим есть проблемы точности: паузы вычисляются со своей точностью, которая не совпадает с делением на доли ритма в треке. Их как правило стараются заменить на кратную смену темпа на что-то < 5 и обратно компенсируют. Для таких дел даже скрипт написан
    • Массив данных — собственно, в каждый шаг трека какая нота должна быть сыграна


    Вот пример для кнопочной ритм-игры: DDR (ITG).
    Там 4 кнопки — поэтому 4 символа в слове для состояния. Разумеется есть редактор, вручную набирать не приходиться:
    Cookie Thumper.sm
    #TITLE:Cookie Thumper;
    #SUBTITLE:;
    #ARTIST:Die Antwoord;
    #TITLETRANSLIT:;
    #SUBTITLETRANSLIT:;
    #ARTISTTRANSLIT:;
    #GENRE:;
    #CREDIT:;
    #BANNER:../banner.png;
    #BACKGROUND:../bg.png;
    #LYRICSPATH:;
    #CDTITLE:;
    #MUSIC:Cookie Thumper.ogg;
    #OFFSET:0.003;
    #SAMPLESTART:48.350;
    #SAMPLELENGTH:12.000;
    #SELECTABLE:YES;
    #BPMS:0.000=134.000,107.000=67.000,143.000=134.000;
    #STOPS:92.000=0.448
    ;
    #BGCHANGES:;
    #KEYSOUNDS:;

    //---------------dance-single — Nix----------------
    #NOTES:
    dance-single:
    Nix:
    Challenge:
    10:
    0.631,0.711,0.437,0.164,0.665:
    0000
    0000
    0000
    0000
    ,
    0000
    0000
    0000
    0000
    ,
    0000
    0000
    0000
    0000
    ,
    0000
    0000
    0000
    0000
    ,
    0000
    0000
    0000
    0000
    ,
    0000
    0000
    0000
    0000
    ,
    2001
    0000
    3100
    1000
    0010
    0100
    0000
    0110
    ,
    0000
    0100
    0001
    0010
    1000
    0000
    0010
    0000
    ,
    0011
    0000
    0001
    0100
    1000
    0100
    0000
    0110
    ,
    0000
    0010
    1000
    0100
    0010
    0000
    0001
    0000
    ,
    1000
    0000
    1000
    0100
    0000
    0100
    0010
    0000
    0001
    0000
    0100
    0010
    1000
    0000
    0100
    0000
    ,
    0010
    0001
    0010
    0100
    0000
    0100
    1000
    0010
    0100
    0000
    0001
    0000
    1001
    0000
    0000
    0001
    ,
    0100
    0010
    1000
    0010
    0000
    0010
    0100
    0001
    0010
    0000
    0100
    0000
    1100
    0000
    0000
    1000
    ,
    0020
    0000
    0230
    0000
    0301
    0100
    0001
    0000
    0101
    0000
    1001
    0000
    2020
    0000
    3030
    0000
    ,
    0120
    0000
    0130
    0001
    0100
    0010
    1000
    0000
    1100
    0000
    0110
    0000
    0011
    0000
    0000
    0000
    ,
    0001
    0000
    0100
    0010
    1000
    0100
    0010
    0001
    1000
    0000
    0010
    0000
    0100
    0000
    0001
    0000
    ,
    0010
    0100
    1000
    0001
    0000
    0001
    1000
    0010
    0100
    0000
    0001
    0000
    0020
    0000
    0000
    0000
    ,
    0030
    0000
    0000
    0000
    0100
    1000
    0100
    0010
    0001
    0000
    0100
    0000
    0110
    0000
    0000
    0000
    ,
    1000
    0010
    0100
    0001
    1000
    0100
    1000
    0001
    0010
    0000
    0100
    0000
    0020
    0000
    0031
    0000
    ,
    0100
    0010
    0000
    1000
    0000
    0010
    0000
    0010
    0100
    0000
    0001
    0000
    1000
    0000
    0100
    0010
    ,
    0001
    0010
    0100
    1000
    0000
    1000
    0001
    0100
    0010
    1000
    0010
    0000
    0100
    0000
    0000
    0000
    ,
    0001
    0010
    0000
    1000
    0000
    0010
    0000
    0100
    1000
    0010
    0100
    0000
    0001
    0000
    0000
    0000
    ,
    1000
    0100
    0010
    0100
    0001
    0100
    0010
    0000
    0022
    0000
    0000
    0000
    0033
    0000
    1000
    0000
    ,
    1010
    0000
    0010
    0100
    0001
    0000
    1000
    0000
    1100
    0000
    0000
    0000
    0100
    0000
    0100
    0010
    ,
    0001
    0010
    0100
    1000
    0001
    0000
    0100
    0000
    0020
    0000
    0000
    0000
    0030
    0000
    0100
    0000
    ,
    0001
    0000
    0000
    0000
    1000
    0000
    1000
    0010
    0100
    0001
    0100
    0000
    0220
    0000
    0330
    0000
    ,
    2002
    0000
    0000
    0000
    0000
    0000
    3003
    0000
    0001
    0000
    1000
    0001
    1000
    0000
    0000
    1000
    ,
    0001
    0100
    0000
    0110
    0000
    0010
    1000
    0100
    0001
    0000
    0100
    0000
    1100
    0000
    0000
    1000
    ,
    0010
    0100
    0000
    0110
    0000
    0100
    0001
    0010
    1000
    0000
    0010
    0000
    0110
    0000
    0100
    1000
    ,
    0010
    0100
    0000
    0101
    0000
    0001
    0010
    1000
    0001
    0000
    0100
    0000
    1100
    0000
    0100
    0010
    ,
    0001
    0000
    0100
    0000
    0000
    0000
    0101
    0000
    0000
    0000
    0001
    0000
    1000
    0010
    1000
    0010
    1000
    0000
    0001
    0100
    0001
    0000
    0001
    0000
    0101
    0000
    0000
    0000
    0000
    0000
    0100
    0000
    ,
    0010
    1000
    0000
    1100
    0000
    0100
    0001
    1000
    0010
    0000
    0100
    0000
    1100
    0000
    1000
    0010
    ,
    0100
    0001
    0000
    0011
    0000
    0010
    1000
    0010
    0001
    0000
    0100
    0000
    0110
    0000
    0010
    0001
    ,
    0010
    1000
    0000
    1010
    0000
    0010
    0001
    1000
    0100
    0000
    0001
    0000
    1001
    0000
    1000
    0100
    ,
    0001
    0000
    0100
    0000
    0000
    0000
    1100
    0000
    0000
    0000
    1000
    0000
    0001
    0010
    0001
    0010
    0001
    0000
    1000
    0100
    1000
    0000
    1000
    0000
    0200
    0000
    0000
    0000
    0000
    0000
    M0MM
    0000
    ,
    0000
    0000
    0000
    0000
    0000
    0000
    M0MM
    0000
    0000
    0000
    0000
    0000
    0000
    0000
    M0MM
    0000
    0000
    0000
    0000
    0000
    0300
    1000
    0001
    0000
    0101
    0000
    0000
    0000
    0000
    0000
    0000
    0000
    ,
    0000
    0000
    0101
    1001
    1010
    1000
    0100
    0010
    ,
    0001
    0000
    0100
    0001
    1000
    0000
    0010
    0000
    0110
    0000
    0000
    0000
    0100
    0001
    1000
    0000
    ,
    0100
    0000
    0000
    0010
    0000
    0000
    0001
    0000
    0000
    0010
    0000
    0000
    0100
    0000
    0000
    0000
    0000
    0000
    1000
    0000
    0000
    0000
    0000
    0000
    0010
    0000
    0000
    0000
    1000
    0000
    0100
    0000
    0000
    0000
    0000
    0000
    1100
    0000
    0000
    0000
    0000
    0000
    0000
    0000
    0000
    0110
    0000
    0000
    ,
    0000
    0000
    0011
    0000
    0000
    1000
    0001
    0000
    1011
    0000
    0000
    1000
    0100
    0000
    0200
    0000
    ,
    0310
    0000
    0001
    0000
    0100
    0000
    1000
    0000
    0100
    0000
    0000
    0000
    0001
    0010
    0000
    1000
    ,
    0000
    0001
    0000
    0100
    0010
    0000
    0001
    0000
    0100
    0000
    0000
    0000
    0010
    1000
    0000
    0001
    ,
    0000
    0100
    0010
    1000
    0100
    0000
    0010
    0000
    0001
    0000
    0000
    0000
    1000
    0100
    0000
    0001
    ,
    0000
    0100
    1000
    0010
    1000
    0000
    0100
    0000
    0010
    0000
    0000
    0010
    0001
    0000
    0100
    0000
    ,
    0010
    0000
    1000
    0010
    1000
    0000
    0100
    0000
    0010
    0000
    0000
    0000
    0010
    0000
    0100
    1000
    ,
    0001
    0100
    0010
    1000
    0100
    0000
    0010
    0000
    0001
    0000
    0000
    1000
    0100
    1000
    0010
    0000
    ,
    0100
    0001
    1000
    0000
    0100
    0000
    0010
    0000
    0001
    0000
    0000
    0000
    0101
    0000
    0110
    0000
    ,
    0010
    0000
    1000
    0010
    1000
    0010
    0100
    0000
    0001
    0000
    0010
    0000
    1000
    0000
    0010
    0000
    ,
    0100
    0000
    1000
    0000
    0010
    0100
    0010
    0000
    1000
    0000
    0000
    0000
    0101
    0000
    0001
    0000
    ,
    0010
    0000
    0100
    1000
    0001
    1000
    0010
    0000
    0100
    0000
    0110
    0000
    1010
    0000
    0001
    0010
    ,
    0100
    1000
    0100
    0010
    0001
    0000
    1000
    0000
    0010
    0000
    0100
    0000
    0001
    0010
    0001
    0000
    ,
    0010
    0100
    1000
    0010
    0200
    0000
    0000
    0000
    ,
    0300
    0000
    0000
    0000
    ;
  • Почему, ну почему, эти #?@! придурки используют vi?
    0
    UPD: УПС: опередили выше про avy
    В emacs есть https://github.com/abo-abo/avy
    Очень удобно. Работает, даже если открыто несколько виртуальных окон
  • Хорошо настроенный Emacs
    0
    Я только с третьей попытки залез на emacs. Ни о чём не жалею, да и мне он подходит как нельзя лучше: редактировать разное, скрипты, руби, файлы спец. назначения.
    Хорошо организованные настройки творят чудеса. Это как и в обычном программе: всё на своих местах, классы разложены по модулям, ресурсы по папочкам, тесты в своём месте и т.д. и т.п.

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

    Мне очень сильно помогло вот это: github.com/purcell/emacs.d
    Я форкнул и добавил паручку вещей под себя. Вдруг кому пригодится.
  • Почему не все так просто с MongoDB
    0
    Легко на словах. А на деле не так просто понять.
    Вот я залочил базу (слэйв).
    Я сделал mongodump. Результат — ок. Ошибок не было. Команда успешно завершена.
    Как мне определить, что mongodump отработал не верно?
    Делаю restore — ошибка. Плохие данные? Ошибка в restore?
    А размер 45 GB дампа.

    ПС. И это хорошо, что мы пока коллекции не шардируем. С таким ненадёжным бэкапом если оно упадёт, а все коллекции размазаны по всем базам, до кучи баги роутеров с кэшем, восстановить это будет нереально.

  • Почему не все так просто с MongoDB
    0
    Монгу используем 2.6.6
    Восстанавливаю всегда в пустую базу.
    noIndexRestore + потом руками — в чём смысл? А если я не знаю какие индексы надо создавать. Ковыряться в дампе и искать их?
    А что насчёт автоматизации? Мне надо автоматически раскидывать дампы на разные окружения. И я не могу сделать нормальный restore.

    А как же 3 вида админов: кто не делает бэкапы, кто делает и тот кто проверяет :)
  • Почему не все так просто с MongoDB
    +4
    Вставлю свои 5 копеек. Может кто-то сталкивался и подскажет как решать вопрос.
    Дано: mongodb cluster: 3 config server, 4 shard, каждый shard это реплика из 3х серверов + арбитр.
    Шардирования на уровне коллекций нет. У нас много мелких баз и они равномерно размазаны по шардам.
    Кластер приложения. Рядом с каждой нодой стоит router.

    Баг 1.
    Как воспроизвести точно не знаю. Но сценарий такой:
    1. Создаём базу main (допустим она попала на sh 001)
    2. Пишем туда что-нибудь
    3. Удаляем базу (да. нам иногда надо снести базу полностью чтоб просто её пересоздать)
    4. Создаём её опять (для примера, она попадает на sh 002)
    И вот теперь проблема: роутер через который это делали, знает что база на sh 002. а остальные роутеры видимо хранят кэш и думают что база на sh 001. Последствия катастрофические: пишем документ — ок. тут же читаем — даже базы нету. Или два процесса пишут свои данные в разные базы main.

    Баг 2.
    Я считаю его практически блокером: отсутствие нормального бэкапа. Да, я читал все мануалы, да, я знаю про mms. Сделать консистентный бэкап — та ещё задача. Но я не придираюсь. Я готов и на «хоть какой-нибудь бэкап кое-как».
    Сценарий:
    1. Для бэкапа максимально одновременно я блокирую по одному слэйву из каждого шарда на запись.
    2. Делаю mongodump (отрабатывает успешно) со всех шардов.
    Восстановление: делаю mongorestore — в 70% я получаю duplicate error при попытке построить индекс в конце восстановления. Пробовал и с oplog, и без. Кстати, индекс применяется ДО того как oplog накатывается. Возможно, этот oplog и исправил бы проблему.
    Вывод: бэкап вы сделаете. А вот восстановить — как повезёт.
    Тут есть ещё разные варианты: я тестировал бэкап через LVM + тянуть прямо с файлов, а не из процесса. Работает стабильнее. Вероятно придётся перейти на этот способ.

    Баг 3.
    Мутный баг. Иногда просто нельзя удалить коллекцию или базу. Помогает рестарт роутеров.

    И это я только с позиции админа. С позицию девелопера я лучше промолчу.

  • Когда Chef и Puppet — не решение. Часть 1
    0
    Что конкретно у вас с версиями в Chef не получается?
  • Chef для решения повседневных задач
    0
    Если у вас 100+ серверов и chef-client установлен в режиме демона (крутится как клиент, на машине), осторожнее с:

    remote_file 'prog' do
      path "#{Chef::Config[:file_cache_path]}/#{package_name}"
      source "http://domain.lan/packages/#{package_name}"
      mode 0644
    end
    

    У вас там наверное трафик с этого сервера большой идёт. Каждый запуск chef-client перекачивает этот файл.
  • Chef для решения повседневных задач
    0
    Я думал, Facebook сидит на Chef. А есть где почитать как и когда они перешли на cfengine.

    И мне не совсем понятен вопрос производительности? Какая разница 100, 1000, 10000? Точнее, она там есть, но тогда причём тут руби?
  • Howto Qemu-kvm Debian 8
    +3
    Всю жизнь пользуюсь aptitude.
    Нигде ничего не сломалось. ЧЯДНТ?
  • Тизер «Бэтмена против Супермена»
    0
    В отличии от Супермена, Бэтмэну нужно потратить время на то, чтобы этот криптонит взять и ещё умудриться напасть на Супермена с ним.
    Супермен же, в свою очередь, может держаться на расстоянии 100 км и при первом же намёке, что Бэт задумал что-то неладное, скинуть на него целую гору. В данном случае, Супермен — это НЕ сбалансированный персонаж. Имба. И всё тут.
  • Berkshelf и зависимости Chef cookbook-ов
    0
    Возможно вам поможет паттерн wrapped-cookbook: я его использую гораздо шире, чем даже описано в комьюнити.

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

    berks update community-cookbook 
    

    и смотрю, что получилось
  • Администрируем сервера через единую консоль
    0
    Мне не понравился в базе capistrano, который очень сильно заточен под rails и я взял его модуль sshkit и сделал более generic библиотеку. Будет время — выложу на github. Идея проста: выполнять rake-таски на всех серверах как на одном (похож на python-овский fabric). Но, разумеется, ему нужен ssh.

    Если у вас windows, то нужен хотя бы cygwin.
    Но это всё слишком серьёзный подход. Возможно, и должен, вас заинтересует rundeck.
    Эти вещи хорошо решают императивные задачи: что запустить, что сделать.

    Configuration Management Systems (Chef, Puppet, Ansible) не всегда со старта могут быть полезны. Поверьте, я много работал, с тем же Chef-ом. Они требуют со старта много знаний, и могут потратить больше времени, чем принести пользы.

    Ну и холивара, ради: Моё первое правило при работе с автоматизацией под Windows:
    Никогда не работать с windows!
  • Как самому сделать танцевальную платформу для Dance Dance Revolution
    +1
    Не удержался, чтоб не закинуть своё детище:
    jsirex.livejournal.com/27049.html