среда, 9 августа 2017 г.

Запись многих каналов с pulseaudio

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

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

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

Решил записать на будущее тот способ что для меня работает.
Просто оказалось невероятно.

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

Нужно сделать новый фейковый sink, и туда отправить и выход на наушники и вход с микрофона.

Делается так:
1. Создадим null-sink
pactl load-module module-null-sink sink_name='foo'

2. Создадим два loopback
pactl load-module module-loopback
pactl load-module module-loopback

3. Назначим источники для loopback

4. Откроем pavucontrol и отправим оба loopback на новый null поток
5. Запустим запись, например в audacity и назначим ей входной поток этот самый null

Удивительным образом прекрасно работает.

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

Если знаете метод лучше - пожалуйста делитесь.

суббота, 22 июля 2017 г.

Дополнительные мониторы

При современной разработке всё время не хватает мониторов.

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

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

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

Я после многих экспериментов остановился на двух, меньше головой крутить.

Конечно же tiling window manager  но в добавок к ним хочется какие то маленькие девайсы индикаторы, загорелось красным - билд не прошел значит.

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

Итак рецепт.

Запускаем vncserver -а, сколько нужно. По одному на доп. устройство.

Конектимся к ним с устройства любым vnc клиентом, по вкусу.

И в этот момент возникает проблема, управлять то неудобно. Пока там на мелком планшете запустишь браузер с дашбоардом - всё на свете проклянешь.

И вот тут приходит на помощь чудесная утилитка x2x.
Которая цепляет один x server к другому как продолжение.

Т.е. запустив x2x -east -to :1 , я прицеплю :1 икс сервер к своему рабочему справа.
Сдвинул мышь за пределы экрана и вот твой ввод и клавиатуа и мышь попадает уже в :1, не нужно никаких ухищрений, всегда работаешь с одной клавой.

Описывать сложно но попробовав думаю сразу оцените.

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


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


воскресенье, 16 июля 2017 г.

Tooling для golang: autorun

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

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

К счастью такая нашлась. Добрые люди посоветовали beego/bee. Не смотря на то что это само по себе какой то фреймворк, я использую только одну часть из него, а именно bee run в текущем каталоге.

И оно всё очень правильно делает, убивает запущеный процесс, перекомпилирует, и перезапускает.

С учётом почти мгновенной компиляции golang это именно то что хотелось.

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

среда, 12 июля 2017 г.

Tooling для golang: Tests

Несмотря на то, что часто можно слышать жалобы про недостаточный tooling в golang, я бы с этим с этим несогласился.

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

go test работает, но хочется красивости, наглядности и автоматизации.

Помучившись немного с ручными скриптами на inotifywatch, бросил это и нашел
Goconvey https://github.com/smartystreets/goconvey решает все эти проблемы изящно.

Запускаешь его и на порту 8080 получаешь сайтик с результатами твоих тестов в приятном виде.

Само перезапускается, показывает, уведомляет и прочее.

Оно включает собственную библиотеку с функциями типа assert, но я не использую, даже без этого уже достаточно полезно.



пятница, 30 июня 2017 г.

Как кодогенерация спасает мир

Была свежая задача модифицировать довольно древний код: 2012 год, perl, всё как всегда.

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

В старом проекте использовалась довольно большая схема базы данных, десятки таблиц, ORM и писать типовые sql запросы мне наскучило за десять минут.

Погуглил немножко и нашел  https://github.com/knq/xo который кодогенерацией запросто решает проблему запросов на CRUD для единичных объектов, получить, сохранить, взять зависимый.

Особенно понравилось в его архитектуре вынесенные templates.
Лучше было 20 минут потерять на настройку их, и получать шикарные файлы моделей.

Нерешенной осталась задача когда нужно было получать списки объектов что то типа scan.

Можно наверное было и это описать в шаблонах, но я сходу не осилил, и нашел scaneo.

Один мелкий патч (пока в апстрим не приняли можно здесь увидеть) https://github.com/korjavin/scaneo и он уже умеет игнорировать служебные поля xo и генерит отличные сканеры.

В итоге, два пакета для кодогенерации, и пакет моделей готово.

Однако, надо понимать что это совсем ещё не ОРМ. Сохранить/Достать объект он может уже, но вот запросы sql для сканеров ещё нужно генерировать.

И тут мне помог https://github.com/Masterminds/squirrel

с их способом

sql, _, _ := 
 psql.Select("*").From("elephants").Where("name IN (?,?)", "Dumbo", "Verna")

 уже вполне можно жить.

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

суббота, 25 февраля 2017 г.

Удаленная переустановка Linux по ssh

Наткнулся тут на очень интересную статью на хабре.

Вот эту: https://habrahabr.ru/post/321696/.

Автор молодец, серьезно, не rocket science, но всё методично и последовательно логично изложено.

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

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

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

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

Там всё идёт отлично до момента, когда нужно создавать lvm разделы.

Т.е. выполняем:


mkdir /target
mount none -t tmpfs -o size=1G /target/
apt-get -y install debootstrap
debootstrap jessie /target/ http://mirror.mephi.ru/debian/
echo "Killer_system" > /target/etc/debian_chroot
 
chroot /target
mount none -t proc /proc/
mount none -t sysfs /sys/
mount none -t devtmpfs /dev/
mount none -t devpts /dev/pts/

apt-get -y install lvm2 debootstrap
apt-get -y install openssh-server openssh-client openssh-blacklist openssh-blacklist-extra --no-install-recommends
sed -i 's/^Port .*$/Port 11122/' /etc/ssh/sshd_config
sed -i 's/^PermitRootLogin .*$/PermitRootLogin yes/' /etc/ssh/sshd_config
/etc/init.d/ssh restart
 
 
 ssh ... -l root -p 11122
 
 dd if=/dev/zero of=/dev/sda bs=1M count=100
 echo 1 > /sys/block/sda/device/delete
 for i in /sys/class/scsi_host/host?/scan ; do echo "- - -" > $i ; done
 
 fdisk /dev/sdb
n<CR> <CR> <CR> <CR>
t<RC> 8e<CR>
w<CR>
 
pvcreate /dev/sdb1
vgcreate vg_root /dev/sdb1
lvcreate -Zn -L500M -n lv_swap0 vg_root

И внезапно въезжаем вот в это:
 Когда исправить уже ничего нельзя.

А всего лишь забыли что lvm2 то на хост системе не было, и модуль не загружен.
Надо было этим на живой ещё хост системе озаботиться поставить lvm2.

Ещё мне кажется автор забыл инструкцию  
vgscan --mknodes
после создания lvm томов

Во всяком случае в моём прогоне на vagrant который я сегодня делал файлы устройств без неё не создавались.
Т.е. полный листинг должен быть такой:


lvcreate -Zn -L500M -n lv_swap0 vg_root
lvcreate -Zn -L1G -n lv_root vg_root
lvcreate -Zn -L2G -n lv_usr vg_root
lvcreate -Zn -L2G -n lv_var vg_root
lvcreate -Zn -L1G -n lv_var_log vg_root
lvcreate -Zn -L1G -n lv_home vg_root
 
vgscan --mknodes 
 
mkswap /dev/vg_root/lv_swap0
mkfs.ext4 /dev/mapper/vg_root-lv_root
mkfs.ext4 /dev/mapper/vg_root-lv_usr
mkfs.ext4 /dev/mapper/vg_root-lv_var
mkfs.ext4 /dev/mapper/vg_root-lv_var_log
mkfs.ext4 /dev/mapper/vg_root-lv_home

mkdir /target
mount /dev/mapper/vg_root-lv_root /target/
mkdir /target/usr /target/var /target/home
mount /dev/mapper/vg_root-lv_usr /target/usr
mount /dev/mapper/vg_root-lv_var /target/var
mkdir /target/var/log
mount /dev/mapper/vg_root-lv_var_log /target/var/log
mount /dev/mapper/vg_root-lv_home /target/home


Всё остальное в статье отлично, после ребута видим свеженькую систему с lvm

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

пятница, 10 февраля 2017 г.

Golang и воздух свободы

Спустя пяток проектов на golang, и учитывая тот факт что я теперь на нём пишу практически ежедневно, уже можно уверенно сказать что инструмент достойный.

Заходило сложновато, это да. Но зато прямо перелом сознания произошёл.

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

Что не сделает теория категорий и монады тебя более счастливым котиком чем старый добрый си на современный лад.

Внезапно полюбил простоту и статическую компиляцию.

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

Как человек измученный cpan, pip и прочим, как страдающих от огромного зоопарка оборудования, я полюбил это всем сердцем.
И это правда развязывает тебе руки не только как девопсу, но и как програмисту.
Чего толку беспокоится о том что ты притащил внешнюю зависимость если в этом больше нет боли. Прямо совсем нет.
Раньше я из за каждой зависимости мучительно страдал, смогу ли я обеспечить её на всех хостах, как это на что повлияет, дак ведь ещё и не угадаешь порой. Всё в прошлом. Алилуйя.

Все эти страдания по дебагерам, дженерикам и прочему попросту мернут на фоне этого.

Действительно дебажить принтами вполне себе можно.

То что язык прост, тоже плюс, да, меньше думаешь о do-нотации монад, зато берешь любой код, и сразу ясно что там.

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

Каналы, горутины - просто прекрасно, даже хвалить не буду, надо просто брать и юзать их.

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

Всё это вместе правда даёт мне ощущение полёта. Как по утюгу с каждой ноги сбросил.

И конечно это сказывается на производительности и общей довольности, аж волосы опять стали расти.

Жаль я не заметил его пару лет назад, стоило.


среда, 8 февраля 2017 г.

Приватный registry для docker с let's encrypt и http basic auth

Появилась необходимость держать репозиторий с докер образами локально.

Супер секретные, все дела.

Короткая шпаргалка.

1. Получаем сертификат от let's encrypt.

На этой неделе мой любимый способ это getssl на баше (https://github.com/srvrco/getssl).

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

./getssl -c domain.com
Правим конфиг по подсказкам и
./getssl domain.com
В крон ставим
getssl -a -q -u 
раз в пару недель.

2. Качаем образ registry:2
 docker pull registry:2
3. Создаем пароли для наших юзеров

mkdir auth
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd
4. Запускаем всё вместе

docker run -d -p 5000:5000 --restart=always --name registry \
  -v `pwd`/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -v /path/.getssl/domain.com:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.com.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.com.key \
registry:2
5. Пробуем с клиентской машины
docker login domain.com
и оно не работает у меня потому как мне в дебиан не завезли ещё корневой сертификат от let's encrypt.
Чинится это просто
scp domain.com:.getssl/domain.com/chain.crt ./
sudo  mv chain.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
6. Тегируем образ
docker tag oldtag domain.com:5000/newtag
7. Заливаем
docker push domain.com:5000/newtag

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

воскресенье, 5 февраля 2017 г.

Чудеса на виражах, в этот раз lvm snapshot

Во время совершенно обычного планового ребута один из debian серверов вдруг не поднялся.

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

Идиотизм конечно: ни рутовую, ни какую либо важную для сервисов, тем не менее загрузка невозможна.

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

Там lvm группа, конечно же, и один из snapshot оказался переполненным и как следствие inactive.

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

Ну вот как это назвать приличным словом?

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

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

Семейство шрифтов input

 По совету умпутуна набрел тут на семейство шрифтов input.

И прямо таки полюбил их.


Что моноширинный, что пропорциональный , оба хороши.


А я на liberation шрифтах просидел тут лет пять наверное зазря.








вторник, 15 ноября 2016 г.

Mysql mass insert

Обычная задача, вставить стопицот миллион записей в mysql.

Так как записи нужно особым образом обрабатывать. то через load data их незагрузишь.

Что приходит в голову первым делом для упрощения вставки, для её ускорения?

Ну prepared statements, окей, делаем:



stmt1, err := db.Prepare("INSERT IGNORE INTO table (a1,a2) VALUES (?,?)")
if err != nil {
  log.Fatalf("mysql: %s", err)
}

for scanner.Scan() {
...
_, err := stmt1.Exec(a1, a2)
if err != nil {
  log.Fatal(err)
}
}
Понятный логичный код. Делал так всю жизнь, привык.

Результат для 64446 записей -  10 минут. Ужас.

Второй вариант, лепим огроменный запросище, клеим его на лету в строку, жрем память, и потом шлем в mysql


sqlStr := "INSERT INTO cats1 (name,url) VALUES "
vals := []interface{}{}
for scanner.Scan() {
..
  sqlStr += "(?,?),"
  vals = append(vals, a1, a2)
}
sqlStr = sqlStr[0 : len(sqlStr)-1]
stmt1, err := db.Prepare(sqlStr)
if err != nil {
  log.Fatalf("mysql: %s ", err)
}
_, err = stmt1.Exec(vals...)
if err != nil {
  log.Fatal(err)
}

Даже выглядит отвратительно, результат для этих же записей - 5 секунд.

Жизнь боль, да.

среда, 2 ноября 2016 г.

golang crossplatform compilation

Я понемногу, когда доходят руки переписываю разные системные утилиты с перлов и питонов на golang.

Конечно ж не специально, то что не сломано я не чиню почти никогда.

Но если работа требует внести изменения в скрипт. то скорее всего я его перепишу на go.

У меня до сих пор довольно много зоопарка в продакшене, включая фряхи всех видов и сортов.

Это останавливало меня от переписывания ряда скриптов, ибо еще полгода назад хорошего способа кросплаформенной сборки не было, а собирать на рабочих серверах не моя страсть.

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

И конечно ж, теперь работает, причем работает, ну жесть как просто.
env GOOS=freebsd GOARCH=amd64 go build -v
и вперед.
Потестировал уже у себя в разных вариантах и где собирать и для чего собирать.

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


Больше подробностей есть по этой ссылке http://dave.cheney.net/2015/08/22/cross-compilation-with-go-1-5

вторник, 6 сентября 2016 г.

Golang дотянулся и до меня

Закончив второй проект на golang за который мне заплатили, можно наверно уже с уверенностью сказать что golang я попробовал.

Конечно же, я всё ещё новичок с очень поверхностным взглядом, и с частичным пониманием.

Но разве ж это мне помешает поделиться кое какими впечалениями.

1. Порой компиляция это прекрасно.

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

В этом смысле очень оценил компилятор который хоть немножко для тебя старается.

2. Скорость, тысяча чертей.

И вправду прекрасна. Причем любая. И компиляции и исполнения.

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

А тут переписал на golang, в рамках другого проекта, и черт возьми,  как же прекрасно стал он работать.

3. Вечные стоны про отладчик

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

4. Зависимости и вендоринг.

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

5. Обработка ошибок.

Я понимаю идею, заставить нас их обрабатывать, и даже поддерживаю её.
Но мой код быстро превращается в лестницу из if-ов

if err ! ... {
  ...
  bla, err : = my...
  if err ! ... {
Наверняка как то это решено в мире go, но я не дошел до понимания, киньте статьей чтоль.

6. vim-go

vim-go как тулинг меня вполне устроил, форматирования, подсказки, окно ошибок, всё ок.
Очень приятное впечатление, и особенно приятно что можно начать немедленно, на фоне последней мой неудачи со Scala.

7. Freebsd

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


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

воскресенье, 4 сентября 2016 г.

Scala, исповедь неудачника и немного про тулинг (от слова tool)


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

И вот опять. видимо этой самой гибкости мне не хватает.

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

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

Они ставят sbt, intellij idea, и какой то  плагин к идее.
Я повторяю всё это за ними. Повторял трижды!
Там есть видео, есть текстовая версия, ошибиться вроде бы негде.

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

А, я теперь понимаю почему оно спрашивает "Точно хотите закрыть идею", да. Перезапуск конкретно крадёт у вас от рабочего дня.

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

Пройдя всё это, я получаю отличный от авторов курса результат.

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

Никакие самостоятельные копания в настройках этого ада мне не помогли.

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

Эмм, это просто изумительный результат.

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

Первый из гугловых результатов по "vim scala"
http://vimawesome.com/plugin/vim-scala указывает  на 502 Bad Gateway, что видимо должно намекнуть.

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

Такое вот нытьё. Куда ж его как не в персональный бложек то? Самое место!

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

Он что, у них такой же? Закрыл IDE, и всё, смело иди в поликлинику очередь занимай, а компиляция проекта повод для отпуска?

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

А теперь вот и поверить сложно.