Files
fission-console/doc/report-2026-04-26-layer2-console.md
T
2026-04-27 07:36:06 +03:00

196 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Отчёт 2026-04-26 — Layer2 console, live validation и причина NodeJS сбоя
## Цель
Зафиксировать текущее состояние Layer2 API и console UI в репозитории fission, задокументировать выполненные live-проверки и отдельно разобрать корневую причину, по которой NodeJS-функции раньше создавались, но не вызывались.
## Что было сделано в этой сессии
### 1. Namespace status/debug приведён к реальному layer1 поведению
Старый код статуса namespace не соответствовал watcher-based схеме из layer1. В console backend логика была перепривязана к реальной модели readiness и bootstrap.
Сделано:
- добавлена актуальная проверка состояния namespace и control-plane;
- добавлен debug endpoint для UI;
- wiring зарегистрирован в HTTP server.
Основные точки:
- [console/internal/api/ns_status.go](console/internal/api/ns_status.go)
- [console/internal/api/server.go](console/internal/api/server.go)
### 2. UI стал показывать прогресс и причины задержек
В UI добавлена более явная обратная связь по долгим операциям:
- таймер deploy/invoke;
- стадия выполнения;
- причина задержки, если функция ещё не готова;
- более явное сообщение об ошибке invoke/deploy.
Это было нужно для демонстрации: пользователь не должен видеть просто зависание без контекста.
Основная точка:
- [console/ui/index.html](console/ui/index.html)
### 3. Go выведен из текущего demo-сценария
Go не удалялся из backend-логики целиком, но был исключён из текущего UI create-flow и из оперативного demo-фокуса. Причина практическая: это единственный компилируемый язык в текущем наборе, а на стенде он зависал на build pending и не был нужен для ближайшей демонстрации.
Основная точка:
- [console/ui/index.html](console/ui/index.html)
### 4. NodeJS починен на уровне packaging + entrypoint compatibility
Это был главный runtime-дефект в конце сессии.
Изменения:
- backend-упаковщик NodeJS теперь экспортирует сразу `main`, `handler` и `default`;
- UI-шаблон NodeJS создаёт новые функции с entrypoint `main`;
- добавлен узкий unit-test на содержимое zip wrapper.
Основные точки:
- [console/internal/runtime/nodejs.go](console/internal/runtime/nodejs.go)
- [console/internal/runtime/nodejs_test.go](console/internal/runtime/nodejs_test.go)
- [console/internal/runtime/entrypoint.go](console/internal/runtime/entrypoint.go)
- [console/ui/index.html](console/ui/index.html)
## Почему NodeJS не работал
### Симптом
Свежесозданная NodeJS-функция успешно создавалась, package имел `buildstatus: none`, poolmgr pod поднимался, но invoke стабильно возвращал timeout:
`invoke "node-..." timeout after 20s: function specialization likely failed`
### Что показала диагностика
В кластере у сломанной функции одновременно наблюдалось следующее:
1. В backend default entrypoint для NodeJS уже был `main`.
См. [console/internal/runtime/entrypoint.go](console/internal/runtime/entrypoint.go).
2. В UI исторический шаблон NodeJS создавал функцию с entrypoint `handler`.
3. Генерируемый `main.js` wrapper не экспортировал именованные entrypoint-ы `main` и `handler` одновременно. По факту он не обеспечивал совместимость между старым UI-поведением и backend default semantics.
4. В результате в `Function.spec.package.functionName` оказывался `handler`, а в содержимом package literal не было гарантированной совместимой named export для этого имени.
5. Fission specialization доходил до стадии загрузки кода, но не мог корректно разрешить entrypoint и заканчивал таймаутом specialization.
### Корневая причина
Корневая причина была не в builder, не в Package CRD и не в самом создании environment.
Проблема была в несовместимости между:
- ожидаемым именем entrypoint в Function spec;
- историческим значением entrypoint из UI;
- фактически экспортируемыми символами в NodeJS wrapper.
Коротко: backend и UI расходились по имени entrypoint, а zip wrapper не был сделан обратносуместимым.
### Исправление
В [console/internal/runtime/nodejs.go](console/internal/runtime/nodejs.go) wrapper был изменён так, чтобы:
- разрешать user code как function, default, handler или main;
- экспортировать `__invoke` сразу как `main` и как `handler`;
- сохранить также `default` export.
Ключевой фрагмент поведения теперь такой:
- поиск callable идёт через `_fn.default || _fn.handler || _fn.main`;
- наружу wrapper экспортирует `main`, `handler`, `default`.
Это снимает несовместимость и для старых client-side ожиданий, и для нового backend default entrypoint.
### Проверка исправления
1. Unit validation:
- `go test ./internal/runtime ./internal/api ./cmd/server` — PASS.
2. Live rollout:
- выкачен image `naeel/fission-console:v0.8.17`;
- deployment `fission-console` успешно обновлён до этого образа.
3. Live retest после rollout:
- создана свежая NodeJS-функция через public console API;
- create вернул `201`;
- первый же invoke вернул `200` и `node-fix-ok`.
Вывод: проблема была именно в entrypoint/export compatibility, и на новых функциях после rollout она устранена.
Важно: уже созданные до фикса NodeJS-функции не чинятся автоматически, потому что их старый package literal уже записан в кластере.
## Что проверено живыми тестами
### Языки
К моменту завершения фикса подтверждено:
- Python: deploy/invoke PASS;
- PHP: deploy/invoke PASS;
- Ruby: deploy/invoke PASS;
- NodeJS: после выката `v0.8.17` deploy/invoke PASS на свежей функции;
- Go: исключён из текущего demo-path.
- Perl: исключён из текущего demo-path после нестабильного specialization в `perl-env`.
### Многопользовательский сценарий
Прогон с 10 параллельными пользователями показал:
- `CREATE_OK=10/10`;
- `INVOKE_OK=10/10`.
Отдельно ранее наблюдался шум на первичном init (`GET /functions`) с частью ответов `000000`, то есть проблема была не в create/invoke-конвейере, а в кратковременной нестабильности первичного запроса или timeout-режима самого тестового скрипта.
## Что важно помнить перед следующим циклом тестов
1. Для длинных прогонов на этом стенде безопаснее использовать self-completing SSH-команды с жёсткими timeout, а не фоновые или интерактивные сценарии.
2. Для NodeJS нужно тестировать только новые функции, созданные уже после rollout исправленного console image.
3. Для demo сейчас приоритетны Python, NodeJS, PHP, Ruby.
4. Go в UI скрыт намеренно и не должен снова появиться в create-flow до отдельного решения по builder path.
## Автоочистка test namespace
После серии прогонов на стенде начали накапливаться десятки и сотни user namespace от тестов. Это мешает ручной диагностике и засоряет cluster state.
Чтобы это больше не копилось:
- добавлен helper [cleanup_test_namespaces.sh](cleanup_test_namespaces.sh);
- [tests_v2.sh](tests_v2.sh) теперь в `trap EXIT` удаляет все namespace, созданные своими test sub;
- [test_multitenant_ns.sh](test_multitenant_ns.sh) тоже удаляет свои namespace по завершении, включая аварийный выход.
Дополнительно на стенде был запущен разовый cleanup накопившихся test namespace с префиксами `fission-`, `diag-`, `l1-test-`, `rbac-verify-`, `sa-verify-`.
## Следующий шаг
Следующий практический шаг после этого отчёта:
- удалить все текущие Fission-функции и managed namespaces;
- затем прогнать новый набор тестов с нуля;
- отдельно включить сценарии, которые имитируют пользовательские ошибки в UI: пустые поля, дубли, неверный entrypoint, плохой код, ранний invoke и повторные клики.
## Обновление: удаление Perl из demo-path
После отдельной проверки выяснилось, что Perl ломается не только в multi-tenant console path, но и на обычном single-user Fission через `simple-perl-env` в `default` namespace. Поэтому для demo-path Perl был отключён на стороне console.
Что изменено:
- Perl убран из UI create-flow;
- Perl убран из supported language map console-side;
- Perl убран из `ai/check` language set;
- Perl убран из live regression сценариев demo-path.
Live rollout:
- собран и выкачен image `naeel/fission-console:v0.8.19`;
- deployment `fission-console` обновлён до `naeel/fission-console:v0.8.19`;
- rollout completed successfully.
Что проверено после rollout `v0.8.19`:
- `go test ./internal/... ./cmd/server/...` — PASS;
- `bash ./test_linters.sh` — PASS (`PASS=31 FAIL=0`);
- `KUBECTL_DIRECT=1 ./test_ui_user_flows.sh` — PASS (`PASS=26 FAIL=0`), после усиления invoke-диагностики и разведения Python / Node / PHP+Ruby по разным user namespaces;
- `KUBECTL_DIRECT=1 ./smoke_live_multiuser.sh 10``CREATE_OK=10/10`, `INVOKE_OK=10/10`, но первичный init дал `INIT_OK=6/10` из-за кратковременных `GET /functions -> 000000`;
- после добавления retry в init: `KUBECTL_DIRECT=1 ./smoke_live_multiuser.sh 10``INIT_OK=10/10`, `CREATE_OK=10/10`, `INVOKE_OK=10/10`;
- новый параллельный сценарий `KUBECTL_DIRECT=1 ./smoke_user_journeys.sh 5``USER_JOURNEYS_PASS=5/5`;
- Python / NodeJS / PHP / Ruby demo-path остаются рабочими;
- Perl отсутствует в live UI surface намеренно.
Отдельно зафиксирована причина ложного падения прежнего `test_ui_user_flows.sh`: это был не баг PHP/Ruby runtime и не ошибка create-path, а quota одного user namespace. Когда в одном и том же namespace последовательно держались Python, NodeJS update и затем PHP/Ruby poolmgr pod'ы, Fission ловил `exceeded quota: user-quota, requested: limits.cpu=1, used: limits.cpu=4, limited: limits.cpu=4`, после чего invoke возвращал `timeout after 20s: function specialization likely failed`. Для live user-flow smoke сценарии были разведены по разным test users/namespaces, сохранив совместную проверку PHP+Ruby в одном namespace.
Дополнительно исправлены сами тесты:
- `test_multitenant_ns.sh` больше не использует устаревший SSH key path;
- `test_multitenant_ns.sh` теперь JSON-экранирует многострочный Python code payload при create function.