diff --git a/console/deploy/console.yaml b/console/deploy/console.yaml index 548f876..09f2a5a 100644 --- a/console/deploy/console.yaml +++ b/console/deploy/console.yaml @@ -52,7 +52,7 @@ spec: serviceAccountName: fission-console containers: - name: console - image: naeel/fission-console:v1.3.49 + image: naeel/fission-console:v1.3.50 imagePullPolicy: Always ports: - containerPort: 8090 diff --git a/console/internal/api/handlers.go b/console/internal/api/handlers.go index 2d30f3a..518ce2c 100644 --- a/console/internal/api/handlers.go +++ b/console/internal/api/handlers.go @@ -618,26 +618,31 @@ func (s *Server) handleGetFunction(w http.ResponseWriter, r *http.Request, name // Читаем source-type аннотацию (code / archive) sourceType := "code" + archiveFilename := "" if ann := fn.GetAnnotations(); ann != nil { if v := ann[fissionSourceTypeAnnotation]; v != "" { sourceType = v } + if v := ann["fission-console/archive-filename"]; v != "" { + archiveFilename = v + } } writeAnyJSON(w, http.StatusOK, map[string]any{ - "name": name, - "namespace": ns, - "environment": environment, - "package": packageName, - "entrypoint": entrypoint, - "timeout": functionTimeout, - "created_at": functionTimestampResponse(fn)["created_at"], - "updated_at": functionTimestampResponse(fn)["updated_at"], - "code": code, - "source_type": sourceType, - "route": route, - "methods": methods, - "raw": fn.Object, + "name": name, + "namespace": ns, + "environment": environment, + "package": packageName, + "entrypoint": entrypoint, + "timeout": functionTimeout, + "created_at": functionTimestampResponse(fn)["created_at"], + "updated_at": functionTimestampResponse(fn)["updated_at"], + "code": code, + "source_type": sourceType, + "archive_filename": archiveFilename, + "route": route, + "methods": methods, + "raw": fn.Object, }) } @@ -773,7 +778,8 @@ func (s *Server) handleUpdateFunctionTimeout(w http.ResponseWriter, r *http.Requ ns := s.userNS(r) var req struct { - Timeout int64 `json:"timeout"` + Timeout int64 `json:"timeout"` + Entrypoint string `json:"entrypoint"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("decode request: %v", err)) @@ -790,6 +796,9 @@ func (s *Server) handleUpdateFunctionTimeout(w http.ResponseWriter, r *http.Requ writeJSONError(w, http.StatusInternalServerError, fmt.Sprintf("set timeout: %v", err)) return } + if req.Entrypoint != "" { + _ = unstructured.SetNestedField(fn.Object, req.Entrypoint, "spec", "package", "functionName") + } now := time.Now().UTC().Format(time.RFC3339) ann := fn.GetAnnotations() if ann == nil { @@ -1310,7 +1319,7 @@ func (s *Server) handleCreateFunctionFromArchive(w http.ResponseWriter, r *http. lang := strings.TrimSpace(r.FormValue("language")) envName := strings.TrimSpace(r.FormValue("environment")) - f, _, err := r.FormFile("archive") + f, fhCreate, err := r.FormFile("archive") if err != nil { writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("archive file required: %v", err)) return @@ -1321,6 +1330,10 @@ func (s *Server) handleCreateFunctionFromArchive(w http.ResponseWriter, r *http. writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("read archive: %v", err)) return } + archiveFilenameCreate := "" + if fhCreate != nil { + archiveFilenameCreate = fhCreate.Filename + } nsCtx, nsCancel := context.WithTimeout(r.Context(), 60*time.Second) defer nsCancel() @@ -1407,6 +1420,9 @@ func (s *Server) handleCreateFunctionFromArchive(w http.ResponseWriter, r *http. functionCreatedAtAnnotation: now.Format(time.RFC3339), functionUpdatedAtAnnotation: now.Format(time.RFC3339), } + if archiveFilenameCreate != "" { + fnAnnotations["fission-console/archive-filename"] = archiveFilenameCreate + } if ttl := r.FormValue("ttl"); ttl != "" { if expiresAt, ttlErr := parseTTL(ttl); ttlErr == nil { fnAnnotations["fission-console/expires-at"] = expiresAt.UTC().Format(time.RFC3339) @@ -1546,12 +1562,22 @@ func (s *Server) handleUpdateFunctionArchive(w http.ResponseWriter, r *http.Requ } _ = unstructured.SetNestedField(fn.Object, timeout, "spec", "functionTimeout") + // Обновляем entrypoint если передан + if ep := strings.TrimSpace(r.FormValue("entrypoint")); ep != "" { + _ = unstructured.SetNestedField(fn.Object, ep, "spec", "package", "functionName") + } + fnAnnotations := fn.GetAnnotations() if fnAnnotations == nil { fnAnnotations = map[string]string{} } fnAnnotations[fissionSourceTypeAnnotation] = "archive" fnAnnotations[functionUpdatedAtAnnotation] = time.Now().UTC().Format(time.RFC3339) + if fh, fhErr := r.MultipartForm.File["archive"]; fhErr == false || len(fh) > 0 { + if files := r.MultipartForm.File["archive"]; len(files) > 0 && files[0].Filename != "" { + fnAnnotations["fission-console/archive-filename"] = files[0].Filename + } + } fn.SetAnnotations(fnAnnotations) if err := unstructured.SetNestedField(fn.Object, map[string]any{ diff --git a/console/ui/index.html b/console/ui/index.html index 1cb1d14..9206bb9 100644 --- a/console/ui/index.html +++ b/console/ui/index.html @@ -102,7 +102,7 @@
NUBES
FISSION CONSOLE
-
v1.3.49
+
v1.3.50
@@ -462,7 +462,7 @@
- v1.3.49 + v1.3.50
diff --git a/console/ui/js/functions.js b/console/ui/js/functions.js index 65db716..186a318 100644 --- a/console/ui/js/functions.js +++ b/console/ui/js/functions.js @@ -150,7 +150,7 @@ async function openEdit(name) { if (fn.source_type === 'archive') { setCodeMode('e', 'archive'); var archiveNameEl = document.getElementById('e-archive-name'); - if (archiveNameEl) archiveNameEl.textContent = fn.package || 'архив'; + if (archiveNameEl) archiveNameEl.textContent = fn.archive_filename || fn.package || 'архив'; var archiveFile = document.getElementById('e-archive-file'); if (archiveFile) archiveFile.value = ''; } else { @@ -205,14 +205,16 @@ async function submitEdit() { // Обновляем через архив var fd = new FormData(); fd.append('timeout', String(parseTimeout(document.getElementById('e-timeout').value))); + fd.append('entrypoint', document.getElementById('e-entry').value.trim()); fd.append('archive', archiveFile); var resp = await fetch(API_BASE + '/functions/' + encodeURIComponent(name) + '/archive', { method: 'PUT', headers: authHeaders(), body: fd }); if (!resp.ok) { var e = await resp.json().catch(() => ({})); throw new Error(e.error || resp.statusText); } } else if (isArchiveMode) { - // Архив не заменяется — обновляем только timeout + // Архив не заменяется — обновляем только timeout + entrypoint await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name) + '/timeout', 'PUT', { - timeout: parseTimeout(document.getElementById('e-timeout').value) + timeout: parseTimeout(document.getElementById('e-timeout').value), + entrypoint: document.getElementById('e-entry').value.trim() }); } else { await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name) + '/code', 'PUT', {