diff --git a/doc/PLAN_MULTI_LANGUAGE.md b/doc/PLAN_MULTI_LANGUAGE.md new file mode 100644 index 0000000..1c0a352 --- /dev/null +++ b/doc/PLAN_MULTI_LANGUAGE.md @@ -0,0 +1,399 @@ +# План: поддержка всех языков Fission + +**Дата:** 2026-04-15 +**Исполнитель:** Sonnet / GPT 5.3 Codex (AI-агент) +**Цель:** Добавить рабочие функции на Go, Java, .NET, Ruby, Rust, PHP — и ПРОТЕСТИРОВАТЬ каждую + +--- + +## Текущее состояние + +| Язык | Статус | Проблемы | +|---|---|---| +| Python | ✅ Работает | — | +| Node.js | ✅ Работает | — | +| Go | ❌ Timeout | Runtime compilation > 20s specialization timeout | +| Java | ❌ Не развёрнуто | — | +| .NET | ❌ Не развёрнуто | — | +| Ruby | ❌ Не развёрнуто | — | +| Rust | ❌ Не развёрнуто | — | +| PHP | ❌ Не развёрнуто | — | + +--- + +## КРИТИЧЕСКИЕ ПРАВИЛА (обязательно для агента) + +1. **ВСЕ КОМАНДЫ — ТОЛЬКО ЧЕРЕЗ SSH:** +```bash +ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 'КОМАНДА' +``` + +2. **Файлы редактировать можно локально** — `/home/naeel/remote_dev/fission/` = `~/terra/fission/` на VM + +3. **Terraform деплой:** +```bash +ssh ... 'cd ~/terra/fission/examples/FOLDER && TF_CLI_CONFIG_FILE=/tmp/terraformrc-fission terraform apply -auto-approve' +``` + +4. **Проверка функции (JWT обязателен):** +```bash +ssh ... ' +PASSWORD=$(kubectl -n fission get secret router -o jsonpath={.data.password} | base64 -d) +TOKEN=$(curl -sk -X POST https://fission.kube5s.ru/auth/login -H "Content-Type: application/json" -d "{\"username\":\"admin\",\"password\":\"$PASSWORD\"}" | python3 -c "import sys,json; print(json.load(sys.stdin)[\"accesstoken\"])") +curl -sk -w "\nHTTP=%{http_code}\n" -H "Authorization: Bearer $TOKEN" https://fission.kube5s.ru/ENDPOINT +' +``` + +5. **НЕ ТРОГАТЬ существующие функции** — 15 шт., список в copilot-instructions.md + +--- + +## Шаг 0: Проверить доступность образов (ОБЯЗАТЕЛЬНО ПЕРВЫМ) + +Перед созданием — проверить что образы exist на ghcr.io: + +```bash +ssh ... ' +for lang in go java jvm dotnet dotnet20 ruby perl php binary; do + echo "--- $lang ---" + # Попробовать pull (dry-run) + docker pull ghcr.io/fission/${lang}-env:latest 2>&1 | head -3 + echo +done +' +``` + +Если образ не найден — попробовать варианты: +- `ghcr.io/fission/go-env` +- `ghcr.io/fission/jvm-env` (Java = JVM в Fission!) +- `ghcr.io/fission/dotnet20-env` или `ghcr.io/fission/dotnet-env` +- `ghcr.io/fission/ruby-env` +- `ghcr.io/fission/php-env` +- `ghcr.io/fission/binary-env` (для предкомпилированных) +- `ghcr.io/fission/perl-env` + +Если образ не существует — НЕ создавать функцию, пропустить язык. + +--- + +## Шаг 1: Go (ПРОБЛЕМНЫЙ — требует особого подхода) + +### Проблема +Go env компилирует код при specialization → timeout 20s → функция не работает. + +### Решение: использовать `binary-env` +Go компилируется на VM → заливается как бинарник → binary-env его запускает. + +**Или:** увеличить specialization timeout через InvokeStrategy: +```yaml +spec: + InvokeStrategy: + ExecutionStrategy: + ExecutorType: newdeploy # вместо poolmgr + MinScale: 1 # always running + MaxScale: 3 +``` + +### Вариант A: pre-compiled + binary-env +``` +examples/go-hello/ +├── code/ +│ └── main.go # исходник для справки +├── build.sh # скрипт для компиляции +└── main.tf +``` + +**build.sh:** +```bash +#!/bin/bash +cd code +CGO_ENABLED=0 GOOS=linux go build -o handler main.go +``` + +**main.tf** — использовать `binary-env` вместо `go-env` + +### Вариант B: newdeploy executor +В Terraform manifests задать `executor_type = "newdeploy"` и `min_scale = 1`. +Проверить поддерживает ли наш провайдер эти аргументы: +```bash +ssh ... 'grep -r "executor\|newdeploy\|min_scale\|invoke_strategy" ~/terra/fission/internal/' +``` + +### Код функции (main.go): +```go +package main + +import ( + "net/http" +) + +func Handler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("Hello from Go in Fission")) +} +``` + +### Тест: HTTP 200, body содержит "Hello from Go" + +--- + +## Шаг 2: Java (JVM) + +### Образ: `ghcr.io/fission/jvm-env` + +### Структура: +``` +examples/java-hello/ +├── code/ +│ └── io/fission/Function.java +└── main.tf +``` + +### Код: +```java +package io.fission; + +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; + +public class Function implements io.fission.Function { + @Override + public ResponseEntity call(RequestEntity req, io.fission.Context context) { + return ResponseEntity.ok("Hello from Java in Fission"); + } +} +``` + +**ВАЖНО:** Проверить точный интерфейс JVM env. Может потребоваться другой формат: +```bash +ssh ... 'docker run --rm ghcr.io/fission/jvm-env:latest cat /app/README.md 2>/dev/null || echo "No README"' +``` + +### main.tf: +```hcl +resource "fission_environment" "jvm" { + name = "tf-jvm-hello-env" + image = "ghcr.io/fission/jvm-env" + version = 3 +} +# ... стандартный pattern +``` + +### Тест: HTTP 200, body содержит "Hello from Java" + +--- + +## Шаг 3: PHP + +### Образ: `ghcr.io/fission/php-env` + +### Структура: +``` +examples/php-hello/ +├── code/ +│ └── hello.php +└── main.tf +``` + +### Код: +```php +&1' +``` + +Если нет — пропустить. Rust можно реализовать через `binary-env` (pre-compiled). + +--- + +## Шаг 7: Perl (бонус) + +### Образ: `ghcr.io/fission/perl-env` + +```perl +sub main { + return "Hello from Perl in Fission"; +} +``` + +--- + +## Порядок выполнения (ВАЖНО) + +``` +1. Проверить доступность ВСЕХ образов (docker pull) → составить список реальных +2. Для каждого доступного языка: + a. Создать examples/LANG-hello/code/... + main.tf + b. terraform apply + c. curl с JWT → проверить HTTP 200 + ожидаемый body + d. Если не работает — смотреть логи: + kubectl -n default get events --sort-by=".lastTimestamp" | tail -20 + kubectl -n default get pods | grep poolmgr-LANG + kubectl -n default logs -c --tail=30 + e. Если timeout — попробовать newdeploy executor + f. Если всё равно не работает — удалить через terraform destroy +3. Обновить список в консоли (она автоматически видит новые функции) +4. Протестировать все через консоль (invoke) +5. Коммит + пуш + тег +``` + +--- + +## Критерий успеха + +| Язык | Endpoint | Ожидаемый body | HTTP | +|---|---|---|---| +| Go | `/go-hello` | `Hello from Go in Fission` | 200 | +| Java | `/java-hello` | `Hello from Java in Fission` | 200 | +| PHP | `/php-hello` | `Hello from PHP in Fission` | 200 | +| Ruby | `/ruby-hello` | `Hello from Ruby in Fission` | 200 | +| .NET | `/dotnet-hello` | `Hello from .NET in Fission` | 200 | +| Perl | `/perl-hello` | `Hello from Perl in Fission` | 200 | + +**Минимум:** 3 новых языка работают (Go + ещё 2) +**Идеал:** все 6 + +--- + +## Шаблон main.tf (копировать и менять) + +```hcl +terraform { + required_providers { + fission = { + source = "nail/fission" + version = "~> 0.1.0" + } + } +} + +provider "fission" { + kubeconfig_path = "/home/naeel/.kube/config" + namespace = "default" +} + +resource "fission_environment" "env" { + name = "tf-LANG-hello-env" + image = "ghcr.io/fission/LANG-env" + version = 3 +} + +resource "fission_package" "pkg" { + name = "tf-LANG-hello-pkg" + environment = fission_environment.env.name + source_dir = "${path.module}/code" +} + +resource "fission_function" "fn" { + name = "tf-LANG-hello-fn" + environment = fission_environment.env.name + package_name = fission_package.pkg.name + entrypoint = "ENTRYPOINT" +} + +resource "fission_http_trigger" "route" { + name = "tf-LANG-hello-route" + function = fission_function.fn.name + url = "/LANG-hello" + methods = ["GET"] +} +``` + +--- + +## Entrypoint для каждого языка + +| Язык | Entrypoint | Файл | +|---|---|---| +| Python | `main.main` | `main.py` | +| Node.js | `module.exports` (пустой) | `server.js` | +| Go | `Handler` | `main.go` | +| Java | `io.fission.Function` | `Function.java` | +| PHP | `hello` | `hello.php` | +| Ruby | `hello.main` | `hello.rb` | +| .NET | `FissionFunction.Execute` | `FissionFunction.cs` | +| Perl | `hello.main` | `hello.pm` | + +**⚠️ ВНИМАНИЕ:** Entrypoints могут отличаться от указанных! Проверять документацию каждого env: +```bash +ssh ... 'docker run --rm ghcr.io/fission/LANG-env:latest env 2>/dev/null | head -20' +``` + +--- + +## Откат при неудаче + +Если язык не работает: +```bash +ssh ... 'cd ~/terra/fission/examples/LANG-hello && TF_CLI_CONFIG_FILE=/tmp/terraformrc-fission terraform destroy -auto-approve' +rm -rf examples/LANG-hello/ +```