From d9a6d2f29eef15e81735dc8f2e0812be34785e75 Mon Sep 17 00:00:00 2001 From: Naeel Date: Wed, 15 Apr 2026 11:00:00 +0300 Subject: [PATCH] fix(console): decode zip package literal before showing code in UI --- console/deploy/console.yaml | 2 +- console/main.go | 82 +++++++++++++++++++++++++++++++++++-- doc/progress.md | 17 ++++++++ 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/console/deploy/console.yaml b/console/deploy/console.yaml index b170251..b7997da 100644 --- a/console/deploy/console.yaml +++ b/console/deploy/console.yaml @@ -46,7 +46,7 @@ spec: serviceAccountName: fission-console containers: - name: console - image: naeel/fission-console:v0.2.3 + image: naeel/fission-console:v0.2.4 ports: - containerPort: 8090 env: diff --git a/console/main.go b/console/main.go index cd9667a..b471a4c 100644 --- a/console/main.go +++ b/console/main.go @@ -1,6 +1,7 @@ package main import ( + "archive/zip" "bytes" "context" "encoding/base64" @@ -10,9 +11,11 @@ import ( "log" "net/http" "os" + "sort" "strings" "sync" "time" + "unicode/utf8" "fission-console/ui" @@ -340,9 +343,8 @@ func (s *server) handleGetFunction(w http.ResponseWriter, r *http.Request, name if pkgErr == nil { literal, _, _ := unstructured.NestedString(pkg.Object, "spec", "deployment", "literal") if literal != "" { - decoded, decErr := base64.StdEncoding.DecodeString(literal) - if decErr == nil { - code = string(decoded) + if decodedCode, decErr := decodeLiteralToSource(literal); decErr == nil { + code = decodedCode } } } @@ -702,3 +704,77 @@ func normalizeMethods(in []string) []string { } return out } + +func decodeLiteralToSource(literal string) (string, error) { + decoded, err := base64.StdEncoding.DecodeString(literal) + if err != nil { + return "", err + } + + if utf8.Valid(decoded) { + return string(decoded), nil + } + + if len(decoded) >= 4 && bytes.Equal(decoded[:4], []byte{'P', 'K', 3, 4}) { + if src, zipErr := decodeZipSource(decoded); zipErr == nil { + return src, nil + } + } + + return string(decoded), nil +} + +func decodeZipSource(zipBytes []byte) (string, error) { + reader, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes))) + if err != nil { + return "", err + } + + preferred := []string{"main.py", "main.js", "main.go"} + for _, name := range preferred { + for _, file := range reader.File { + if strings.EqualFold(file.Name, name) { + content, readErr := readZipFile(file) + if readErr != nil { + return "", readErr + } + if utf8.Valid(content) { + return string(content), nil + } + } + } + } + + files := make([]*zip.File, 0, len(reader.File)) + for _, file := range reader.File { + if file.FileInfo().IsDir() { + continue + } + files = append(files, file) + } + sort.Slice(files, func(i, j int) bool { + return files[i].Name < files[j].Name + }) + + for _, file := range files { + content, readErr := readZipFile(file) + if readErr != nil { + continue + } + if utf8.Valid(content) { + return string(content), nil + } + } + + return "", fmt.Errorf("zip archive does not contain utf-8 source files") +} + +func readZipFile(file *zip.File) ([]byte, error) { + rc, err := file.Open() + if err != nil { + return nil, err + } + defer rc.Close() + + return io.ReadAll(rc) +} diff --git a/doc/progress.md b/doc/progress.md index b5eb1c3..1723376 100644 --- a/doc/progress.md +++ b/doc/progress.md @@ -285,3 +285,20 @@ ### Ограничения - Runtime-проблемы Fission (зависания на cold start/таймауты выполнения) в этом изменении не трогались: исправлен только provider-слой валидации и обнаружения изменений. + +## 2026-04-15 (дополнение) — Fix отображения кода в Console UI + +### Проблема +- В модальном окне редактирования функции (`Edit Code`) для некоторых пакетов отображались байты ZIP (`PK...`) вместо исходного кода. + +### Причина +- `GET /console/api/functions/{name}` декодировал `spec.deployment.literal` только из base64, но не обрабатывал архивированный payload. + +### Исправление +- В `console/main.go` добавлено декодирование `literal` с поддержкой ZIP: + - если payload plain text/utf-8 -> отдаётся как есть + - если payload ZIP -> извлекается `main.py`/`main.js`/`main.go` (или первый utf-8 файл) +- Обновлён deployment image: `naeel/fission-console:v0.2.4`. + +### Проверка +- `GET /console/api/functions/fn-go-acc` теперь возвращает читаемый Go-код, без `PK...` сигнатур.