Из каждого чайника слышу про ZED, это такой новомодный IDE от авторов Atom. Славится своей скоростью и минимализмом, никаких тебе новогодних ёлок и перегруженных интерфейсов. Чем-то напоминает VIM.
ㅤ
Дошли руки потыкать. Но одного желания мало, под винду сука дистрибутив не завезли. Хочешь под винду? Скомпилируй из исходников!
😀 😃 😄 😁 😅 😂 🤣 😊
😇 🙂 🙃 😉 😌 😍 🥰 😘
😗 😙 😚 😋 😛 😝 😜 🤪
🤨 🧐 🤓 😎 🤩 🥳 😏 😒
Да легко! Спустя 4 часа ебатни и дебага — спасибо, идите нахуй!
Залил в себя пару пиалок до-хун-пао, словил дзен и нашел выход.
Пиздуем на сайт и ищем ZED. Ебала жаба гадюку! Всё уже придумано и собрано за нас. Верните мне 4 часа компиляции!
Открываем CMD и хуячим:
Всё!
Если не установлен
Что по IDE?
Моё почтение, все нужные мне плагины по девопсовым делам — есть. Даже маркдаун и превью работает. Шикарно!
Из коробки есть подключение к удаленным серверам. То есть подключаешься к своему удаленному серверу разработки и пишешь код. В лучших традициях VSCode.
Чтобы по умолчанию в качестве терминала у тебя не открывался CMD, делаем финт ушами и дружим ZED с WSL.
Теперь открывается ZSH, или что там у тебя установлено в WSL.
Больше добавить пока нечего, всё нравится. Буду тыкать, а там уже посмотрим.
🛠 #windows #ide #dev
—
✅ @bashdays ✅ @linuxfactory ✅ @blog
ㅤ
Дошли руки потыкать. Но одного желания мало, под винду сука дистрибутив не завезли. Хочешь под винду? Скомпилируй из исходников!
Да легко! Спустя 4 часа ебатни и дебага — спасибо, идите нахуй!
Если официальный мануал по компиляции писала жопорукая обезьяна, тут уже ничего с этим не поделаешь.
Залил в себя пару пиалок до-хун-пао, словил дзен и нашел выход.
Пиздуем на сайт и ищем ZED. Ебала жаба гадюку! Всё уже придумано и собрано за нас. Верните мне 4 часа компиляции!
Открываем CMD и хуячим:
scoop bucket add extras
scoop install extras/zed
Всё!
Если не установлен
scoop, ставим так:Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
Что по IDE?
Моё почтение, все нужные мне плагины по девопсовым делам — есть. Даже маркдаун и превью работает. Шикарно!
Из коробки есть подключение к удаленным серверам. То есть подключаешься к своему удаленному серверу разработки и пишешь код. В лучших традициях VSCode.
Чтобы по умолчанию в качестве терминала у тебя не открывался CMD, делаем финт ушами и дружим ZED с WSL.
"terminal": {
"shell": {
"program": "C:\\Windows\\System32\\wsl.exe"
},
"font_family": "Hack Nerd Font Mono",
"font_size": 15,
"line_height": "standard"
}Теперь открывается ZSH, или что там у тебя установлено в WSL.
Ааа, забыл, в ZED можно подключить ИИ агенты, причем можешь локально поднять дипсик или т.п. и использовать его прям в IDE.
Больше добавить пока нечего, всё нравится. Буду тыкать, а там уже посмотрим.
—
Please open Telegram to view this post
VIEW IN TELEGRAM
1 49
Как не стремись к автоматизации, всегда найдется какой-нибудь легаси сервис, который требует ручного обслуживания.
Был у меня такой сервис и работал он только тогда, когда все его файлы и каталоги принадлежали определенному пользователю.
ㅤ
Доступ к сервису имели многие, поэтому люди порой троили и запускали команды в каталоге сервиса от root. Сервису было на это поебать, но до момента его перезапуска.
Обычно это чинилось очень легко, через
Казалось бы, есть масса способов предотвратить такие ошибки: правильные права на файлы, ACL’ы, SELinux.
Но веселья в этом мало! Поэтому я решил заебенить свой собственный мониторинг файловой системы. Скиллов то предостаточно, хули нет.
Спойлер:Я залез в кроличью нору и знатно так хлебнул гавна.
Попытка намбер 1
В Linux есть API под названием fanotify, с его помощью можно получать события о действиях с файлами в юзерспейс.
Всё просто: инициализируем fanotify_init, указываем каталоги через fanotify_mark и читаем события из дескриптора.
Но тут же вылез огромный хуй:
- нельзя отслеживать каталоги рекурсивно (только целый маунт)
-
Решение вполне рабочее, но громоздкое. Я такие не люблю, этож думать надо, вайбкодингом не решается.
Попытка намбер 2
Вспоминаем что есть
В
То есть единая точка входа. Там можно отлавливать события и фильтровать их, не гоняя лишние переключения контекста.
Но и тут вылез хуй:
-
- фильтрацию приходится писать прямо в
Да блядь…
Как я победил рекурсивный обход
Чтобы понять, что именно меняется в каталоге сервиса, пришлось использовать структуру
Но так как в
На практике этого вполне достаточно. Глубина каталогов мне известна. Ну и конечно, пришлось аккуратно работать с RCU-локами, чтобы дерево не поменялось в момент обхода.
Как можно улучшить
В идеале использовать не VFS-хуки, а LSM hooks (Linux Security Module).
Они стабильнее, понятнее и позволяют сразу работать с путями. Там можно красиво получить path и сразу преобразовать его в строку, а потом делать поиск подстроки.
Но в моём ядре этих хуков не было, хуй знает почему, видимо дистрибутив слишком древний. Надо попробовать на новых, чем черт не шутит.
Итоги
Эта поделка как и предполагалась, погрузила меня в печаль, душевные страдания, НО стала отличным тренажером для прокачки:
- Внутренностей Linux ядра
- Работы с eBPF
- И кучу другого с kernel-space
Информации по нему много, но вся она разбросана. Собрать всё это в кучу было отдельным квестом.
Мораль?
Иногда самое простое решение — это
🛠 #linux #debug #dev
—
✅ @bashdays ✅ @linuxfactory ✅ @blog
Был у меня такой сервис и работал он только тогда, когда все его файлы и каталоги принадлежали определенному пользователю.
ㅤ
Доступ к сервису имели многие, поэтому люди порой троили и запускали команды в каталоге сервиса от root. Сервису было на это поебать, но до момента его перезапуска.
Обычно это чинилось очень легко, через
chown -R. Все это знали и никого это не смущало. Короче костыль ебаный.Казалось бы, есть масса способов предотвратить такие ошибки: правильные права на файлы, ACL’ы, SELinux.
Но веселья в этом мало! Поэтому я решил заебенить свой собственный мониторинг файловой системы. Скиллов то предостаточно, хули нет.
Спойлер:
Попытка намбер 1
В Linux есть API под названием fanotify, с его помощью можно получать события о действиях с файлами в юзерспейс.
Всё просто: инициализируем fanotify_init, указываем каталоги через fanotify_mark и читаем события из дескриптора.
Но тут же вылез огромный хуй:
- нельзя отслеживать каталоги рекурсивно (только целый маунт)
-
anotify даёт только PID процесса, который что-то сделал. А чтобы узнать UID/GID — нужно лезть в /proc/<pid>/status. То есть на каждое событие приходится открывать и парсить файлы в /proc.Решение вполне рабочее, но громоздкое. Я такие не люблю, этож думать надо, вайбкодингом не решается.
Попытка намбер 2
Вспоминаем что есть
eBPF. Это штука позволяет запускать программы прямо в ядре Linux. Они компилируются в байткод, проходят проверку, а потом гоняются через JIT почти с нативной скоростью.Что такое eBPF можешь почитать тут и тут.
В
eBPF заебись то, что можно цепляться за разные функции ядра. Например, можно подцепиться к vfs_mkdir или vfs_create — это общий слой для работы с файлами.То есть единая точка входа. Там можно отлавливать события и фильтровать их, не гоняя лишние переключения контекста.
Но и тут вылез хуй:
-
kprobes на функции VFS нестабильны, в новых ядрах сигнатуры могут меняться или функции вообще исчезнуть.- фильтрацию приходится писать прямо в
eBPF, а там свои ограничения. Нет бесконечных циклов, стек всего ~512 байт.Да блядь…
Как я победил рекурсивный обход
Чтобы понять, что именно меняется в каталоге сервиса, пришлось использовать структуру
dentry и подниматься по дереву до родителя.Но так как в
eBPF нельзя сделать «бесконечный» цикл, я ограничил глубину с помощью MAX_DEPTH.На практике этого вполне достаточно. Глубина каталогов мне известна. Ну и конечно, пришлось аккуратно работать с RCU-локами, чтобы дерево не поменялось в момент обхода.
➡️ Кусок кода в первом комментарии, сюда не влез.
Как можно улучшить
В идеале использовать не VFS-хуки, а LSM hooks (Linux Security Module).
Они стабильнее, понятнее и позволяют сразу работать с путями. Там можно красиво получить path и сразу преобразовать его в строку, а потом делать поиск подстроки.
Но в моём ядре этих хуков не было, хуй знает почему, видимо дистрибутив слишком древний. Надо попробовать на новых, чем черт не шутит.
Итоги
Эта поделка как и предполагалась, погрузила меня в печаль, душевные страдания, НО стала отличным тренажером для прокачки:
- Внутренностей Linux ядра
- Работы с eBPF
- И кучу другого с kernel-space
eBPF — мощнейший инструмент, но очень тонкий. Ошибёшься — будешь выебан в жопу.
Информации по нему много, но вся она разбросана. Собрать всё это в кучу было отдельным квестом.
Мораль?
Иногда самое простое решение — это
chown -R. Но куда интереснее — написать свой велосипед и заглянуть в кроличью нору Linux ядра.—
Please open Telegram to view this post
VIEW IN TELEGRAM
9 47
Настройка core dump в Docker
Цель этого поста — дать тебе общее руководство по включению и сбору core dumps для приложений, работающих в docker контейнере.
Настраиваем хост для сохранения дампов
Для начала надо сконфигурировать хостовую машину, чтобы сохранять такие дампы в нужное место. Нет, не в жопу.
ㅤ
Универсальный способ — задать шаблон core pattern. Шаблон определяет путь и информацию о процессе который наебнулся.
Кратенько:
Как вариант, можно настроить host изнутри контейнера через CMD или ENTRYPOINT. Но контейнер в этом случае должен запускаться в privileged mode, что хуева с точки зрения безопасности.
Пример хуёвого приложения
После компиляции и запуска, приложение наебнется с ошибкой.
Пишем Dockerfile для этого приложения
Запускаем контейнер с нужными опциями:
Разбираем опции:
Здесь важно: путь
После того как приложение наебнется, core dump будет сохранён на хостовой машине в директории
Анализируем дамп с помощью gdb
Такс, мы получили core dump и он у нас лежит на хостовой машине, но рекомендуется открыть его внутри контейнера. Контейнер должен быть из того же образа, в котором компилилось приложение.
Это поможет убедиться, что все зависимости (библиотеки и прочая хуитень) доступны.
Если в образе нет исходного кода, можно допом смаунтить исходники:
Теперь внутри контейнера запускаем:
После загрузки дампа можно выполнить команду
Команда поможет определить, где именно произошел факап.
Давай быстренько разберем ошибку.
В исходнике было:
То есть ошибка здесь не баг компиляции или рантайма, а намеренно вставленный вызов
Если у тебя docker-compose, то все флаги (
Хуй знает чё еще написать, завтра тему дебага продолжим, чет в конце года много траблшутинга навалило разнообразного.
🛠 #linux #debug #dev
—
✅ @bashdays ✅ @linuxfactory ✅ @blog
Цель этого поста — дать тебе общее руководство по включению и сбору core dumps для приложений, работающих в docker контейнере.
Настраиваем хост для сохранения дампов
Для начала надо сконфигурировать хостовую машину, чтобы сохранять такие дампы в нужное место. Нет, не в жопу.
ㅤ
Универсальный способ — задать шаблон core pattern. Шаблон определяет путь и информацию о процессе который наебнулся.
echo '/tmp/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern
Кратенько:
%e — имя процесса %p — pid процессаБолее подробно о конфигурации core pattern можешь почитать в man-странице ядра Linux.
Как вариант, можно настроить host изнутри контейнера через CMD или ENTRYPOINT. Но контейнер в этом случае должен запускаться в privileged mode, что хуева с точки зрения безопасности.
Пример хуёвого приложения
#include <cstdlib>
void foo() {
std::abort();
}
int main() {
foo();
return 0;
}
После компиляции и запуска, приложение наебнется с ошибкой.
Пишем Dockerfile для этого приложения
FROM ubuntu:22.04
# Install tools
RUN apt update \
&& apt -y install \
build-essential \
gdb \
&& rm -rf /var/lib/apt/lists/*
# Build the application
COPY ./ /src/
WORKDIR /src/
RUN g++ main.cpp -o app
CMD ["/src/app"]
Тот кто в теме, сможет его прочитать и понять. Если не понятно, гугли и разбирай, качнешь свой девопсовый скиллз.
Запускаем контейнер с нужными опциями:
docker run \
--init \
--ulimit core=-1 \
--mount type=bind,source=/tmp/,target=/tmp/ \
application:latest
Разбираем опции:
--init — гарантирует корректную обработку сигналов внутри контейнера--ulimit — устанавливает неограниченный размер core dump для процессов внутри контейнера--mount — монтирует /tmp из хоста в контейнер, чтобы дампы, создаваемые внутри контейнера, были доступны после его остановки или удаленияЗдесь важно: путь
source на хосте должен совпадать с тем, который задан в шаблоне core pattern.После того как приложение наебнется, core dump будет сохранён на хостовой машине в директории
/tmp. ls /tmp/core*
# /tmp/core.app.5
Анализируем дамп с помощью gdb
Такс, мы получили core dump и он у нас лежит на хостовой машине, но рекомендуется открыть его внутри контейнера. Контейнер должен быть из того же образа, в котором компилилось приложение.
Это поможет убедиться, что все зависимости (библиотеки и прочая хуитень) доступны.
docker run \
-it \
--mount type=bind,source=/tmp/,target=/tmp/ \
application:latest \
bash
Если в образе нет исходного кода, можно допом смаунтить исходники:
docker run \
-it \
--mount type=bind,source=/tmp/,target=/tmp/ \
--mount type=bind,source=<путь_к_исходникам_на_хосте>,target=/src/ \
application:latest \
bash
Теперь внутри контейнера запускаем:
gdb app /tmp/core.app.5
После загрузки дампа можно выполнить команду
bt (backtrace), чтобы увидеть трассировку стека:(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007f263f378921 in __GI_abort () at abort.c:79
#2 0x000055f9a9d16653 in foo() ()
#3 0x000055f9a9d1665c in main ()
Команда поможет определить, где именно произошел факап.
Давай быстренько разберем ошибку.
#0 и #1 показывают, что процесс получил сигнал 6 (SIGABRT) и завершился через abort()#2 — вызов произошёл внутри функции foo()#3 — main() вызвал foo()В исходнике было:
void foo() {
std::abort();
}То есть ошибка здесь не баг компиляции или рантайма, а намеренно вставленный вызов
std::abort(), который и приводит к аварийному завершению и генерации core dump.Если у тебя docker-compose, то все флаги (
--init, --ulimit, --mount и т.д.) применимы и для него. То есть отладку можно легко адаптировать.Хуй знает чё еще написать, завтра тему дебага продолжим, чет в конце года много траблшутинга навалило разнообразного.
—
Please open Telegram to view this post
VIEW IN TELEGRAM
5 45
Сегодня коллега, который проводит дохрена технический собесов поделился инсайдом. Мол кандидаты из Южной Америки часто называют временные переменные
ㅤ
Прикольно. Для меня
А в чем дело-то?
Причины могут быть в языке и в традициях обучения.
Южная Америка и «aux»
Во многих странах Латинской Америки (а также в Испании и Португалии) обучение программированию ведётся на родном языке.
Слово
Поэтому сокращение
Восточная Европа и «temp»
В странах Восточной Европы (Россия, Польша и др.) учебные материалы часто брались с английских источников или напрямую переводились, но при этом терминология частично сохранялась.
В англоязычных книгах традиционное имя временной переменной —
Ещё один фактор — русскоязычные (и в целом восточноевропейские) программисты исторически чаще учились по книгам на английском, чем по локализованным методичкам. Хотя и методичек особо таких и не было.
Давай разберем другие страны
Китай
- В учебниках и коде часто встречается
-
- Булевые переменные часто называются
- Комментарии «中英混合» — смесь китайских и английских терминов:
- В олимпиадном коде часто встречается
Западная Европа / США
- Стандартные учебные названия:
- В учебниках на джава и питоне для временных значений часто используют
- В научном и численном коде — переменные
Ну тут классика, аналогично Мистер и Миссис Стоговы из учебников по инглишу.
Восточная Европа / Россия
-
-
-
Переменные
Комментарии часто начинаются с
Ближний Восток
- В арабоязычных странах иногда встречается
- Комментарии миксуют латиницу и арабицу, например:
Индия
-
- В комментариях любят писать
Названия переменных иногда из «хинди-английского микса» в учебных проектах:
В целом получаем:
- Испаноязычные/португалоязычные —
- Восточная Европа —
- Англоязычные —
- Китай/Индия —
Короче вся это тема — маленькие «акценты» кода. Про 1Сников писать уж не буду, сами все знаете как они переменные называют.
Не смею больше отвлекать, хороших тебе выходных!
🛠 #рабочиебудни #dev
—
✅ @bashdays ✅ @linuxfactory ✅ @blog
aux, а вот кандидаты из Восточной Европы - temp. Такая вот этнография.ㅤ
Прикольно. Для меня
aux это дырка в которую можно что-то вставить.А в чем дело-то?
Причины могут быть в языке и в традициях обучения.
Южная Америка и «aux»
Во многих странах Латинской Америки (а также в Испании и Португалии) обучение программированию ведётся на родном языке.
Слово
auxiliar (испанское) или auxiliar/auxiliaridade (португальское) переводится как «вспомогательный». Поэтому сокращение
aux — это естественный выбор для временной переменной. Многие учебники и преподаватели прямо используют aux в примерах.Восточная Европа и «temp»
В странах Восточной Европы (Россия, Польша и др.) учебные материалы часто брались с английских источников или напрямую переводились, но при этом терминология частично сохранялась.
В англоязычных книгах традиционное имя временной переменной —
temp (от temporary). В итоге это закрепилось как привычка.Ещё один фактор — русскоязычные (и в целом восточноевропейские) программисты исторически чаще учились по книгам на английском, чем по локализованным методичкам. Хотя и методичек особо таких и не было.
То есть это, по сути, отражение того, на каком языке преподавали первые курсы информатики и какие примеры попадались студентам.
Такие мелочи могут «маркировать» культурный бэкграунд разработчика не хуже акцента в речи.
Давай разберем другие страны
Китай
- В учебниках и коде часто встречается
tmp (это короче чем temp).-
arr почти всегда вместо array.- Булевые переменные часто называются
flag.- Комментарии «中英混合» — смесь китайских и английских терминов:
// 计算 sum
total = total + arr[i];
- В олимпиадном коде часто встречается
ans и vis (visited).Западная Европа / США
- Стандартные учебные названия:
temp, foo, bar, baz.- В учебниках на джава и питоне для временных значений часто используют
value или val.- В научном и численном коде — переменные
x, y, z, dx, dy (от физики и математики).Ну тут классика, аналогично Мистер и Миссис Стоговы из учебников по инглишу.
Восточная Европа / Россия
-
temp как временная переменная (от англ. temporary).-
buf вместо buffer (сильно закрепилось ещё с ассемблеров и C-шных примеров).-
cnt для счётчиков (counter) — иногда даже вместо i/j/k.Переменные
res (result) и ans (answer) очень популярны в олимпиадном программировании.Комментарии часто начинаются с
// !!! или // FIXME: на смеси русского и английского.Ближний Восток
- В арабоязычных странах иногда встречается
mosa3ed (مساعد = помощник), но чаще используют англоязычные temp/aux.- Комментарии миксуют латиницу и арабицу, например:
// calculate المجموع
// check if الشرط
// temp متغير
Индия
-
temp тоже стандарт, но часто встречается flag для булевых переменных (очень широко).- В комментариях любят писать
// logic или // main logic, даже если код очевиден.Названия переменных иногда из «хинди-английского микса» в учебных проектах:
num1, chotu (маленький), bada (большой).В целом получаем:
- Испаноязычные/португалоязычные —
aux.- Восточная Европа —
temp/buf/cnt/res.- Англоязычные —
temp/foo/bar.- Китай/Индия —
tmp/flag/arr/ans.Короче вся это тема — маленькие «акценты» кода. Про 1Сников писать уж не буду, сами все знаете как они переменные называют.
Не смею больше отвлекать, хороших тебе выходных!
—
Please open Telegram to view this post
VIEW IN TELEGRAM
8 75
Привет друзья, Масим Братковский запилил для нас техническую статейку.
ㅤ
Сюда по классике не влезло, опубликовал в блоге. Идем читать.
Что делать если postman достал, а надо тестировать SOAP API.
Комментарий автора: Если вам интересно, давайте обратную связь, буду рад продолжить серию статей.
🛠 #dev #qa
—
✅ @bashdays ✅ @linuxfactory ✅ @blog
ㅤ
Сюда по классике не влезло, опубликовал в блоге. Идем читать.
Что делать если postman достал, а надо тестировать SOAP API.
Комментарий автора: Если вам интересно, давайте обратную связь, буду рад продолжить серию статей.
—
Please open Telegram to view this post
VIEW IN TELEGRAM