fix(console): decode zip package literal before showing code in UI
This commit is contained in:
@@ -46,7 +46,7 @@ spec:
|
|||||||
serviceAccountName: fission-console
|
serviceAccountName: fission-console
|
||||||
containers:
|
containers:
|
||||||
- name: console
|
- name: console
|
||||||
image: naeel/fission-console:v0.2.3
|
image: naeel/fission-console:v0.2.4
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8090
|
- containerPort: 8090
|
||||||
env:
|
env:
|
||||||
|
|||||||
+79
-3
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"archive/zip"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
@@ -10,9 +11,11 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"fission-console/ui"
|
"fission-console/ui"
|
||||||
|
|
||||||
@@ -340,9 +343,8 @@ func (s *server) handleGetFunction(w http.ResponseWriter, r *http.Request, name
|
|||||||
if pkgErr == nil {
|
if pkgErr == nil {
|
||||||
literal, _, _ := unstructured.NestedString(pkg.Object, "spec", "deployment", "literal")
|
literal, _, _ := unstructured.NestedString(pkg.Object, "spec", "deployment", "literal")
|
||||||
if literal != "" {
|
if literal != "" {
|
||||||
decoded, decErr := base64.StdEncoding.DecodeString(literal)
|
if decodedCode, decErr := decodeLiteralToSource(literal); decErr == nil {
|
||||||
if decErr == nil {
|
code = decodedCode
|
||||||
code = string(decoded)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -702,3 +704,77 @@ func normalizeMethods(in []string) []string {
|
|||||||
}
|
}
|
||||||
return out
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -285,3 +285,20 @@
|
|||||||
|
|
||||||
### Ограничения
|
### Ограничения
|
||||||
- Runtime-проблемы Fission (зависания на cold start/таймауты выполнения) в этом изменении не трогались: исправлен только provider-слой валидации и обнаружения изменений.
|
- 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...` сигнатур.
|
||||||
|
|||||||
Reference in New Issue
Block a user