Files
sless/examples/DESTROY_ROUTE_CLEANUP_BUG.md
T
“Naeel” 80991d2aab docs: update progress.md, errors/log.md; add gitignore for dist/ and tfstate backups
- doc/progress.md: обновлена версия до operator v0.1.18 / provider v0.1.11,
  добавлен блок source_dir + fix destroy cleanup (2026-03-09),
  уточнены комментарии к контроллерам и trigger_resource
- doc/errors/log.md: добавлены две записи — source_dir/hashicorp/archive,
  destroy route cleanup bug (три причины + решения)
- .gitignore: добавлены examples/*/dist/ и terraform.tfstate.*.backup
- examples/: удалены dist/ zip и tfstate.*.backup из трекинга
2026-03-09 20:29:27 +04:00

143 lines
7.9 KiB
Markdown

# Bug Report: HTTP route is not removed after Terraform destroy
## Summary
При удалении примера `hello-node` через Terraform команда `terraform destroy` завершается успешно, но публичный HTTP endpoint не удаляется.
Фактическое поведение после `destroy` такое:
1. Сразу после удаления endpoint ещё некоторое время отвечает `HTTP 200` и возвращает корректный ответ функции.
2. Затем backend функции действительно исчезает, но публичный маршрут остаётся опубликованным и начинает отвечать `HTTP 502 function unreachable`.
3. Даже через 120 секунд endpoint не исчезает.
Это выглядит как баг cleanup в platform/backend/provider lifecycle для HTTP trigger/route.
## Affected Example
- Example: `hello-node`
- Terraform files: `hello-node/main.tf`, `hello-node/http.tf`, `hello-node/job.tf`
- Public URL: `https://sless-api.kube5s.ru/fn/default/hello-http`
- Function name: `hello-http`
- Trigger name: `hello-http-trigger`
## Reproduction
Использовался репозиторий examples и скрипт:
- Script: `./run_terraform_examples.sh`
Шаги воспроизведения:
1. Выполнить `terraform init` в `hello-node`
2. Выполнить `terraform apply`
3. Убедиться, что endpoint живой
4. Выполнить `terraform destroy`
5. Проверять публичный URL после destroy
Логика проверки встроена в `run_terraform_examples.sh`:
1. После `apply` endpoint обязан отвечать `200`
2. После `destroy` endpoint должен исчезнуть
3. Скрипт ждёт до 120 секунд и перепроверяет endpoint каждые 5 секунд
## Expected Result
После успешного `terraform destroy`:
1. Публичный URL должен перестать существовать
2. Запрос на URL должен вернуть `404` или другой явный признак отсутствия маршрута
3. Provider не должен возвращать успешный destroy раньше, чем cleanup HTTP route завершён
## Actual Result
После успешного `terraform destroy`:
1. Terraform сообщает `Destroy complete! Resources: 4 destroyed.`
2. Endpoint `https://sless-api.kube5s.ru/fn/default/hello-http` продолжает отвечать `200`
3. Через некоторое время тот же endpoint начинает отвечать `502`
4. Тело ответа на `502`:
```json
{"error":"function unreachable: Post \"http://hello-http.sless-fn-default.svc.cluster.local:8080\": dial tcp 10.106.128.167:8080: connect: operation not permitted"}
```
Это означает:
1. внешний HTTP маршрут всё ещё существует;
2. запрос по нему всё ещё направляется внутрь платформы;
3. backend функции уже удалён или недоступен;
4. cleanup маршрута не завершён.
## Timeline From Real Run
Подтверждённая последовательность из фактического прогона:
1. `terraform destroy` завершился успешно
2. первые проверки после destroy возвращали `HTTP 200`
3. затем проверки начали возвращать `HTTP 502 function unreachable`
4. в течение всех 24 проверок по 5 секунд endpoint не исчез
5. итоговое время ожидания: 120 секунд
Итоговый summary из скрипта:
```text
ERROR SUMMARY
example: hello-node
step: endpoint cleanup after clean destroy
reason: route cleanup bug: public endpoint still exists but backend is already gone (HTTP 502 function unreachable); endpoint was still published after 120s
```
## Why This Is A Real Platform Bug
Это не похоже на проблему тестового скрипта или Terraform CLI по следующим причинам:
1. `terraform destroy` завершается без ошибки
2. state Terraform очищается как ожидалось
3. сначала endpoint отвечает `200`, значит маршрут реально жив после destroy
4. потом endpoint отвечает `502 function unreachable`, значит backend уже исчез, но route ещё остался
5. скрипт ждёт 120 секунд, то есть это не мгновенная eventual consistency на 1-2 секунды
Иными словами: удаление backend и удаление публичного маршрута расходятся по времени, а route cleanup либо не выполняется, либо не дожидается завершения.
## Most Likely Broken Layer
Наиболее вероятные точки проблемы:
1. API/backend destroy trigger возвращает success до фактического удаления HTTP route
2. Controller удаляет function workload, но не удаляет route/ingress/virtualservice/gateway mapping
3. Удаление route запускается асинхронно, но его результат не awaited
4. В системе остаётся запись маршрута на имя функции, хотя service/backend уже удалён
## What To Check In The Development Repo
Нужно проверить destroy flow именно для HTTP trigger:
1. Удаляется ли объект trigger только в metadata/storage или реально удаляется и внешний маршрут
2. Какие Kubernetes/ingress объекты создаются для HTTP trigger и все ли они удаляются
3. Есть ли race condition между удалением function/service и удалением route
4. Не возвращает ли provider success раньше, чем backend подтверждает полное удаление маршрута
5. Есть ли финальный polling/wait на исчезновение route перед возвратом успешного destroy
Если архитектура использует отдельные сущности route/service/function, то destroy должен идти в таком порядке:
1. disable/remove public routing
2. дождаться, что endpoint больше не публикуется снаружи
3. удалить backend/service/workload
4. завершить destroy success
Сейчас по фактическому поведению порядок либо обратный, либо неполный.
## Minimal Acceptance Criteria For Fix
Исправление можно считать рабочим, если после `terraform destroy` для `hello-node` выполняются все условия:
1. URL `https://sless-api.kube5s.ru/fn/default/hello-http` перестаёт отвечать как живой маршрут
2. URL не возвращает `502 function unreachable`
3. URL исчезает в разумное время после destroy
4. `./run_terraform_examples.sh` проходит шаг `endpoint cleanup after clean destroy`
## Current Status
На данный момент массовый прогон examples корректно останавливается на `hello-node`, потому что это первый воспроизводимый failure.
Дальше прогонять остальные примеры без исправления destroy cleanup смысла нет: тест уже доказал platform bug на базовом HTTP сценарии.