И туган тел, и матур тел, әткәм-әнкәмнең теле! («О родной язык, о прекрасный язык, язык моих отца и матери!» — Габдулла Тукай, «Туган тел», 1909)

TL;DR. Мы выкатили Татарнетес — национальную обёртку над Kubernetes, где команды, сообщения, ошибки и даже перерывы на чай с чак-чаком и т.п. на татарском. Рядом — TatarOS Linux (обёртка над Talos, которая поднимает кластер с Татарнетесом) и Татарнетес UI (панель на фоне татарского келәма). Всё под собственной лицензией Tatarch 2.0.
Под капотом i18n на чистом bash 3.2 без единой зависимости, три системы письма (кириллица, яңалиф, гарәп язуы), детерминированный чайный график (кластер рандомно останавливается на попить чай с молоком и бабушкиными кыстыбыями) и первый черновик татарской IT-терминологии Kubernetes. А ещё мы прогнали всё на реальном кластере CozyStack — с живыми kubectl/talosctl, RBAC, метриками и одним пойманным багом.
Репозитории tatar-ncf: tatarnetes · tataros · tatarnetes-ui. Лицензия — Tatarch 2.0.
Проект посвящается Саше, Роме, Максу и Рамилю из одного замечательного кубер-чатика.
1. Зачем нам это вообще
Помимо того, что это просто троллинг, у нас была вполне и серьёзная задумка: туган тел (родной язык) заслуживает того, чтобы жить не только в стихах, но и в терминале! Татарской IT-терминологии для cloud-native почти нет: как по-татарски «reconciliation», «ingress», «replica»? Мы решили не ждать, а предложить — пусть спорный, но живой черновик, который можно дополнять через pull request.
Поэтому Татарнетес — это три вещи одновременно: (1) весёлый инструмент, который поднимает настроение; (2) настоящая инженерная песочница по i18n в bash; (3) вклад в цифровизацию языка — глоссарий и локализация, которые может править любой носитель.
2. Почему запуск 20 сентября
Дату выбирали не «для галочки». Конец сентября у татар — муллык чоры, пора изобилия, когда с полей и садов собирают җимеш (плоды). А в нашей лицензии Tatarch 2.0 любое произведение — код, программа, книга — так и называется: «Җимеш», плод труда. Рәхим итегез — угощайтесь.
И приятное совпадение: 20 сентября 1970 года родился татарский писатель и поэт Марат Кәбиров — один из тех, кто первым затащил татарскую литературу в цифру. Литература, ушедшая в код; код, заговоривший на языке литературы — это по-нашему. Так что Татарнетес — это подарок всей татарской земле и международному татарскому сообществу, от Казани до Стамбула, от Хельсинки до Сан-Франциско. Милләтем данлыклы, халкым юмарт, коды ирекле.
3. Демо за 30 секунд
kubectl get pods знает каждый. А теперь:
ayda күрсәт кузаклар
ayda (әйдә — «давай, пошли!») переводит татарскую команду в kubectl и выполняет её.
Ресурсы получили осмысленные татарские имена: под — кузак (стручок, ведь и англ. pod — стручок), node — төен (узел), service — хезмәт, namespace — мәйдан, ingress — капка (ворота), secret — сер, volume — күләм.
При успехе тебя встречает добрая рожица в түбәтәе и хвалит Татарстан; при ошибке — она же, но сердитая, и лёгкое татарское ворчание. Между делом — строка Тукая или горячий эчпочмак.
И — да — обычный kubectl тоже работает: ayda get pods пройдёт насквозь. Есть и krew-плагин: kubectl ayda ....
4. Архитектура: тонкая обёртка
Татарнетес не форкает Kubernetes построчно. Это тонкая, безопасная для пайпов обёртка над kubectl: разобрать татарский, перевести в kubectl, выполнить, обернуть ответ в национальные декорации. Схематично поток такой:
пользователь → ayda (bash) ───────────────→ kubectl → Kubernetes API 1. resolve_verb (глагол, латин-фолбэк) 2. resolve_noun (первый позиционный токен = ресурс) 3. чайный шлюз (tea_now?) 4. запуск + захват stderr 5. рожа/мактау/шелтә + гарнир (всё в stderr)
Строк bash — 1936 (ayda + tos + lib/), и это включает шесть систем письма-логики, i18n-движок, корпус и тесты. Ни одной внешней зависимости, только bash, sed, awk, grep — и целевой bash — 3.2 (тот самый, что стоит на macOS по умолчанию: без ассоциативных массивов, с граблями мультибайта). Это осознанное ограничение: инструмент должен запускаться везде.
5. i18n на чистом bash 3.2
Самое интересное — как локализация живёт без gettext-рантайма.
Источник правды — .po. Строки интерфейса лежат в locale/tt.po (39 msgid) и en.po в обычном gettext-формате, где татарский — канонический:
msgid "err.unknown_verb"msgstr "Мондый әмер юк: «%s»"
Сборка каталога. scripts/build-catalog.sh (awk) генерит из .po чистый bash — case-функцию lib/catalog.sh, чтобы в рантайме не было ни парсинга, ни зависимостей:
catalog_lookup() { # $1=lang $2=key case "$1:$2" in tt:err.unknown_verb) printf '%s' 'Мондый әмер юк: «%s»' ;; en:err.unknown_verb) printf '%s' 'No such command: "%s"' ;; ... *) printf '%s' "$2" ;; esac}
Функция t() достаёт строку, подставляет аргументы и, если язык татарский, прогоняет через транслитерацию:
t() { local key="$1"; shift local fmt; fmt="$(catalog_lookup "$AYDA_LANG" "$key")" local out; out="$(printf "$fmt" "$@")" if [ "$AYDA_LANG" = "tt" ]; then printf '%s' "$out" | alif_render; else printf '%s' "$out"; fi}
Синхронность каталога сторожит CI: отдельный job пересобирает catalog.sh из .po и падает, если появился diff. Так перевод и рантайм не разъезжаются.
Сингармонизм. Множественное число мы не хардкодим, а порождаем по гармонии гласных: суффикс -лар/-ләр (задний/передний ряд), а после носовых м/н/ң — -нар/-нәр:
tn() { # кузак→кузаклар, төен→төеннәр, хезмәт→хезмәтләр, мәйдан→мәйданнар, сер→серләр local w="$1" lastvow lastch front=0 nas=0 lastvow="$(printf '%s' "$w" | grep -oE '[аәоөуүыиеэюёяАӘОӨУҮЫИЕЭ]' | tail -1)" lastch="$(printf '%s' "$w" | grep -oE '.$')" case "$lastvow" in ә|ө|ү|е|и|э|ю|ё|Ә|Ө|Ү|Е|И|Э) front=1 ;; esac case "$lastch" in м|н|ң|М|Н|Ң) nas=1 ;; esac if [ "$front" -eq 1 ]; then [ "$nas" = 1 ] && echo "${w}нәр" || echo "${w}ләр" else [ "$nas" = 1 ] && echo "${w}нар" || echo "${w}лар"; fi}
Всё это покрыто юнит-тестами (28 проверок в tatarnetes, 12 в tataros).
6. Три письменности одного народа
Татарский за век сменил три алфавита — и каждый это культурный пласт. Татарнетес умеет во все три:
AYDA_ALIF=cyrl ayda ярдәм # кириллица (по умолчанию)AYDA_ALIF=latin ayda ярдәм # яңалиф — латиница 1920–30-хAYDA_ALIF=arab ayda ярдәм # яңа имля — татарское арабское письмо
Латиницей можно и вводить команды (для клавиатур без кириллицы). Причём мы не заводили второй словарь: сначала пробуем распознать как есть, а если не вышло — транслитерируем ввод в кириллицу и пробуем снова. Английские kubectl-глаголы при этом не ломаются:
resolve_noun() { local n="$1" r c r="$(translate_noun "$n")"; [ "$r" != "$n" ] && { printf '%s' "$r"; return 0; } # нашли как есть c="$(printf '%s' "$n" | latin_to_cyrl)" # латин → кирилл r="$(translate_noun "$c")" if [ "$r" != "$c" ]; then printf '%s' "$r"; else printf '%s' "$n"; fi # иначе — как ввели}
Арабское письмо (яңа имля, реформа 1920-х) — фонематическое: каждый звук отдельной буквой, все гласные записываются, различаются передний/задний ряд (о ۇ / ө ۆ, у و / ү ۈ). В начале слова гласная получает носитель-хамзу ئ. Выводим в логическом порядке — RTL и соединение букв делает сам терминал. Word-initial hamza добавляем через awk (по словам, byte-safe), а буквы меняем отдельными подстановками:
cyrl_to_arab() { awk '{ n=split($0,a,/ /); o="" for(i=1;i<=n;i++){ w=a[i] if (w ~ /^(а|ә|о|ө|у|ү|ы|и|э|е|я|ю|ё|А|Ә|О|Ө|У|Ү|Ы|И|Э|Е)/) w="ئ" w o=o (i>1?" ":"") w } print o }' \ | sed -e 's/я/یا/g' -e 's/а/ا/g' -e 's/ә/ە/g' -e 's/о/ۇ/g' -e 's/ө/ۆ/g' \ -e 's/у/و/g' -e 's/ү/ۈ/g' -e 's/к/ك/g' -e 's/т/ت/g' ... # по одной букве}
Проверяли не на глаз, а по кодпоинтам:
Татарнетес → تاتارنېتېسU+062A TEH · U+0627 ALEF · U+062A TEH · U+0627 ALEF · U+0631 REH · U+0646 NOON· U+06D0 E · U+062A TEH · U+06D0 E · U+0633 SEEN = т-а-т-а-р-н-е-т-е-с
7. Кластер уходит на чәй
Несколько раз в сутки Татарнетес останавливается на чай с молоком и кыстыбыем. Стучишься в это время — получаешь картинку и вежливое «Кыстырылма, туганкай — безгә дә чәй эчәргә кирәк!».
График детерминированный — выводится из календарного дня, три окна по 7 минут:
tea_windows() { today=$(date +%Y%m%d); seed=$(( 10#$today )); i=1 while [ "$i" -le 3 ]; do m=$(( (seed * (i * 37 + 13) + i * 101) % 1440 )) # минута суток 0..1439 echo "$m 7"; i=$(( i + 1 )) done}
Та же формула зеркалится в ui/app.js (teaWindowsFor), поэтому консоль и браузер видят одинаковые окна до минуты. Пьёт кластер чай по-настоящему везде — в пайпах и в CI тоже: чәй — это чәй, выход 42. Не хочешь ждать — честная кнопка AYDA_NO_TEA=1 (её же используют наши тесты), а форснуть перерыв для демо — AYDA_FORCE_TEA=1. Робот, впрочем, чаю не откажет — просто знает пароль.
8. pipe-safety и перевод ошибок
Весь «арт» (рожа, мактау, гарнир, ковёр) уходит в stderr, а stdout остаётся чистым — поэтому ayda күрсәт кузаклар -o json | jq работает как обычный kubectl. Чтобы при этом перехватить и перевести ошибку, мы жонглируем дескрипторами: stdout ребёнка идёт «насквозь» (fd 3), а stderr ловим в переменную:
{ ERRTEXT="$("$KUBECTL_BIN" "$kverb" ${kargs[@]+"${kargs[@]}"} 2>&1 1>&3 3>&-)"; RC=$?; } 3>&1
Дальше по тексту ошибки подбираем татарскую подсказку, не пряча оригинал: NotFound → «Табылмады — исемен яки мәйданны тикшер», Forbidden → «Рөхсәт юк — хокукларыңны (RBAC) тикшер», timeout, connection refused и т. д.
9. Характер как фичи
Мы старались, чтобы «национальный характер» стал не стереотипом, а полезной фичей.
-
Хуҗалыкчыллык (бережливость). Просишь много реплик — система по-татарски напомнит про экономию: «Акчаны әрәм итмә!» Порог настраивается
AYDA_FINOPS_MAX. -
Кунакчыллык (гостеприимство). При первом заходе в новый контекст тебя встретят как гостя: «Рәхим итегез! Яңа төбәк (контекст): …. Кунагыбыз бул!» (запоминаем последний контекст в
~/.cache/ayda/last_ctx). -
Календарь. По пятницам — «Җомгагыз мөбарәк булсын!», на Нәүрүз/Сабантуй/байрамы — праздничный баннер (даты 2026-го выверены по Указу Раиса Татарстана).
10. Культурный корпус и борьба с галлюцинациями
Стихи и пословицы вынесены в data/*.tt (9 стихотворных фрагментов, 14 пословиц), чтобы носитель мог дополнять их через PR. Здесь у нас железное правило: классику искажать нельзя. Все строки Тукая, Җәлила, Дәрдмәнда, Сибгата Хакима и народные мәкальләр выверены по источникам, а не по памяти нейросети (в data/VERIFICATION.tt.md — таблица источников). Там, где источник не удалось подтвердить, автор в корпус не попал — точность важнее полноты.
11. Лицензия Tatarch 2.0
Юридически Tatarch 2.0 эквивалентна Apache License 2.0 — те же права и условия (грант авторских прав, патентный грант с ретолиацией, четыре условия распространения, отказ от гарантий, ограничение ответственности). Совместимость мы берегли специально. Отличается форма и дух:
-
Эпическая преамбула вместо канцелярии: лицензия открывается словами о славной истории, щедрости и кунакчыллыке татарского народа — и звучит как дастан.
-
«Җимеш». Произведение называется не «Work», а Җимеш (плод), и распространяется «иркен, татар кунакны каршылагандай» («свободно, как татарин встречает гостя»).
-
Народное достояние. Каждое произведение провозглашается духовно принадлежащим всему великому татарскому народу. Тут же — честная юридическая оговорка: это почётное заявление, оно не создаёт имущественных прав, копирайт остаётся у правообладателя. Красивая метафора не должна мешать реальному использованию.
-
Двуязычие, татарский — первым (и вся документация тоже). Латиница/арабица — авто-транслит.
Если коротко: берите так же свободно, как под Apache 2.0 — просто у этой свободы есть түбәтәй.
12. TatarOS Linux и Татарнетес UI
Три проекта складываются в один национальный стек:
TatarOS Linux — обёртка над Talos (иммутабельная ОС для Kubernetes). CLI называется tos и важно отличается идеологически: он поднимает кластер не с Кубернетесом, а с Татарнетесом. tos татарнетес-конфиг выдаёт доступ — и в кластере тебя ждёт саф Татарнетес.
Татарнетес UI — форк официального дашборда: татарская палитра (яшел-ак-кызыл плюс алтын), фон — настоящий татарский келәм (тамга, лаләләр-тюльпаны, ислими-вязь), а идентификаторы нод — это тамга, родовые знаки. В перерыв панель тоже закрывается и показывает шамаиль-баннер.
13. Как проверяли
Тут начинается самое интересное — мы не поверили себе на слово и прогнали всё на реальном кластере CozyStack: изолированный тенант tncf, тенант-Kubernetes на Talos v1.13.6 / k8s v1.35.6 (2 ноды), отдельный kubeconfig, каждая команда с явным --context.
ayda — вся боевая матрица прошла на живом кластере:
|
Проверка |
Факт (live) |
exit |
|---|---|---|
|
|
реальные поды/ноды + оформление в stderr |
0 |
|
|
идентично кириллице |
0 |
|
|
обычный kubectl |
0 |
|
|
|
1 |
|
RBAC: SA без прав |
|
1 |
|
FinOps: |
реально масштабирует до 12 + «Акчаны әрәм итмә! 12 реплика…» |
0 |
|
pipe-safety: |
|
0 |
|
|
латиница / RTL-арабица |
0 |
|
|
— |
64 |
|
|
экран чая |
42 |
Латентность (медиана 5 прогонов): ayda 774 мс vs kubectl 812 мс. Накладные обёртки — в пределах шума (≈0, фактически −5%). То есть «национальный слой» не стоит вам производительности.
tos на настоящем Talos. Против managed-кластера cluster-операции упираются в hosted control-plane (worker-ноды не форвардят tenant-запросы — no request forwarding), поэтому мы подняли отдельную standalone Talos-ноду v1.11.2 и прогнали day-2 глаголы вживую:
-
tos вакыт→ реальные NTP-данные;tos дисклар→ диски;tos сәламәтлек→ health; -
tos яңадан-кабыз→ реальный ребут ноды (actor ID, sequence START, нода ушла и вернулась); -
tos татарнетес-конфиг→ реальный рабочий kubeconfig 2270 байт (CA-data,server:https://10.244.76.195:6443, clustertatarnetes). Хедлайн-фича доказана вживую.
А ещё боем поймали баг. tos күрсәт төеннәр мапился в talosctl get nodes — а у talosctl нет COSI-ресурса nodes (resource "nodes" is not registered), команда всегда падала. Починили: төен → members (cluster.Member), обновили словарь, help, доки и тесты. Это ровно то, ради чего гоняют боем — на моках такое не всплывает.
14. Грабли
Тут всё из кода самого проекта и с боевого прогона:
-
sedна macOS режет по байтам, а не по буквам. Кириллица/арабица — по 2 байта, и класс[Хх]в BSD sed матчит отдельные байты, кроша UTF-8. Из-за этого первая версия арабицы была битой; лечится подстановками по целой букве + проверкой по кодпоинтам. -
Слишком жадный перевод переименовал чужой под. Под, буквально названный
эш(«работа»), команда превращала вget pods jobs. Починка: переводим только первый позиционный токен (тип ресурса), имена и значения флагов не трогаем. -
bash 3.2 и кавычка-ёлочка
«$verb»— многобайтная»«прилипает» к имени переменной; спасают фигурные скобки${verb}. Иprintf "$fmt"с%sбез аргумента молча съедает плейсхолдер. -
[из боя] Talos apid отвергает client-cert без EKU
clientAuth(tls: bad certificate). СамодельныйO=os:admincert из Talos-CA заработал только сextendedKeyUsage=clientAuth. -
[из боя] managed CozyStack = hosted control-plane: worker-Talos не форвардят tenant-запросы;
talosctl versionидёт, аget/health/kubeconfigтребуют standalone control-plane. -
[из боя]
talosctl get nodesне существует — см. выше,төен → members.
15. Итоги и как помочь
Готовность по итогам боевого прогона: ayda и UI — к публичному показу готовы сразу; tos — как обёртка готов, а для «живого» татарнетес-конфиг нужен standalone Talos control-plane (это особенность стенда, не баг).
git clone https://github.com/tatar-ncf/tatarnetes.gitcd tatarnetes && ./install.shayda ярдәм
Помочь просто и приятно:
-
перевести интерфейс — правишь
locale/*.po, шлёшь PR (кода касаться не надо); -
дополнить глоссарий —
docs/terminology.tt.md(сейчас 36 терминов); -
добавить строфу классика — обязательно с указанием источника.
Метрики проекта
|
|
|
|---|---|
|
Строк bash ( |
1936 |
|
Ключей локализации ( |
39 |
|
Терминов в глоссарии |
36 |
|
Юнит-проверок (tatarnetes / tataros) |
28 / 12 |
|
Корпус (стихи / пословицы) |
9 / 14 |
|
Систем письма |
3 (кирилл / яңалиф / яңа имля) |
|
Накладные |
≈0 (−5%) |
|
Репозиториев |
3 |
Галерея
Скринкасты (GIF): тур по консоли (живой прогон) · тур по UI.
Ссылки
Организация: github.com/tatar-ncf — Tatar-Native Computing Foundation
Репозитории:
-
🐘 tatar-ncf/tatarnetes — CLI
ayda, национальный Kubernetes -
🖥 tatar-ncf/tatarnetes-ui — идарә панеле (дашборд)
-
🐧 tatar-ncf/tataros — CLI
tos, TatarOS Linux (даёт Татарнетес)
Полезное:
Йомгак
Мы сделали это, потому что туган тел заслуживает жить и в терминале. Технологии не обязаны быть холодными: пусть кластер носит түбәтәй, угощает чәкчәком и уходит на чай — но при этом честно переводит ошибки, не тормозит и переживает боевой прогон. Всё — под Tatarch 2.0, всё — бөек татар халкына, всему великому татарскому народу и татарам всего мира.
Рәхмәт яугыры! Татарстан алга! Яшә, ирекле код! 🟢⚪🔴
ссылка на оригинал статьи https://habr.com/ru/articles/1084230/