196 lines
13 KiB
Markdown
196 lines
13 KiB
Markdown
# Отчёт 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. |