v1.3.50: fix archive fn — entrypoint update in edit, store/show archive filename
This commit is contained in:
@@ -52,7 +52,7 @@ spec:
|
|||||||
serviceAccountName: fission-console
|
serviceAccountName: fission-console
|
||||||
containers:
|
containers:
|
||||||
- name: console
|
- name: console
|
||||||
image: naeel/fission-console:v1.3.49
|
image: naeel/fission-console:v1.3.50
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8090
|
- containerPort: 8090
|
||||||
|
|||||||
@@ -618,26 +618,31 @@ func (s *Server) handleGetFunction(w http.ResponseWriter, r *http.Request, name
|
|||||||
|
|
||||||
// Читаем source-type аннотацию (code / archive)
|
// Читаем source-type аннотацию (code / archive)
|
||||||
sourceType := "code"
|
sourceType := "code"
|
||||||
|
archiveFilename := ""
|
||||||
if ann := fn.GetAnnotations(); ann != nil {
|
if ann := fn.GetAnnotations(); ann != nil {
|
||||||
if v := ann[fissionSourceTypeAnnotation]; v != "" {
|
if v := ann[fissionSourceTypeAnnotation]; v != "" {
|
||||||
sourceType = v
|
sourceType = v
|
||||||
}
|
}
|
||||||
|
if v := ann["fission-console/archive-filename"]; v != "" {
|
||||||
|
archiveFilename = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeAnyJSON(w, http.StatusOK, map[string]any{
|
writeAnyJSON(w, http.StatusOK, map[string]any{
|
||||||
"name": name,
|
"name": name,
|
||||||
"namespace": ns,
|
"namespace": ns,
|
||||||
"environment": environment,
|
"environment": environment,
|
||||||
"package": packageName,
|
"package": packageName,
|
||||||
"entrypoint": entrypoint,
|
"entrypoint": entrypoint,
|
||||||
"timeout": functionTimeout,
|
"timeout": functionTimeout,
|
||||||
"created_at": functionTimestampResponse(fn)["created_at"],
|
"created_at": functionTimestampResponse(fn)["created_at"],
|
||||||
"updated_at": functionTimestampResponse(fn)["updated_at"],
|
"updated_at": functionTimestampResponse(fn)["updated_at"],
|
||||||
"code": code,
|
"code": code,
|
||||||
"source_type": sourceType,
|
"source_type": sourceType,
|
||||||
"route": route,
|
"archive_filename": archiveFilename,
|
||||||
"methods": methods,
|
"route": route,
|
||||||
"raw": fn.Object,
|
"methods": methods,
|
||||||
|
"raw": fn.Object,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,7 +778,8 @@ func (s *Server) handleUpdateFunctionTimeout(w http.ResponseWriter, r *http.Requ
|
|||||||
ns := s.userNS(r)
|
ns := s.userNS(r)
|
||||||
|
|
||||||
var req struct {
|
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 {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("decode request: %v", err))
|
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))
|
writeJSONError(w, http.StatusInternalServerError, fmt.Sprintf("set timeout: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if req.Entrypoint != "" {
|
||||||
|
_ = unstructured.SetNestedField(fn.Object, req.Entrypoint, "spec", "package", "functionName")
|
||||||
|
}
|
||||||
now := time.Now().UTC().Format(time.RFC3339)
|
now := time.Now().UTC().Format(time.RFC3339)
|
||||||
ann := fn.GetAnnotations()
|
ann := fn.GetAnnotations()
|
||||||
if ann == nil {
|
if ann == nil {
|
||||||
@@ -1310,7 +1319,7 @@ func (s *Server) handleCreateFunctionFromArchive(w http.ResponseWriter, r *http.
|
|||||||
lang := strings.TrimSpace(r.FormValue("language"))
|
lang := strings.TrimSpace(r.FormValue("language"))
|
||||||
envName := strings.TrimSpace(r.FormValue("environment"))
|
envName := strings.TrimSpace(r.FormValue("environment"))
|
||||||
|
|
||||||
f, _, err := r.FormFile("archive")
|
f, fhCreate, err := r.FormFile("archive")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("archive file required: %v", err))
|
writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("archive file required: %v", err))
|
||||||
return
|
return
|
||||||
@@ -1321,6 +1330,10 @@ func (s *Server) handleCreateFunctionFromArchive(w http.ResponseWriter, r *http.
|
|||||||
writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("read archive: %v", err))
|
writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("read archive: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
archiveFilenameCreate := ""
|
||||||
|
if fhCreate != nil {
|
||||||
|
archiveFilenameCreate = fhCreate.Filename
|
||||||
|
}
|
||||||
|
|
||||||
nsCtx, nsCancel := context.WithTimeout(r.Context(), 60*time.Second)
|
nsCtx, nsCancel := context.WithTimeout(r.Context(), 60*time.Second)
|
||||||
defer nsCancel()
|
defer nsCancel()
|
||||||
@@ -1407,6 +1420,9 @@ func (s *Server) handleCreateFunctionFromArchive(w http.ResponseWriter, r *http.
|
|||||||
functionCreatedAtAnnotation: now.Format(time.RFC3339),
|
functionCreatedAtAnnotation: now.Format(time.RFC3339),
|
||||||
functionUpdatedAtAnnotation: now.Format(time.RFC3339),
|
functionUpdatedAtAnnotation: now.Format(time.RFC3339),
|
||||||
}
|
}
|
||||||
|
if archiveFilenameCreate != "" {
|
||||||
|
fnAnnotations["fission-console/archive-filename"] = archiveFilenameCreate
|
||||||
|
}
|
||||||
if ttl := r.FormValue("ttl"); ttl != "" {
|
if ttl := r.FormValue("ttl"); ttl != "" {
|
||||||
if expiresAt, ttlErr := parseTTL(ttl); ttlErr == nil {
|
if expiresAt, ttlErr := parseTTL(ttl); ttlErr == nil {
|
||||||
fnAnnotations["fission-console/expires-at"] = expiresAt.UTC().Format(time.RFC3339)
|
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")
|
_ = 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()
|
fnAnnotations := fn.GetAnnotations()
|
||||||
if fnAnnotations == nil {
|
if fnAnnotations == nil {
|
||||||
fnAnnotations = map[string]string{}
|
fnAnnotations = map[string]string{}
|
||||||
}
|
}
|
||||||
fnAnnotations[fissionSourceTypeAnnotation] = "archive"
|
fnAnnotations[fissionSourceTypeAnnotation] = "archive"
|
||||||
fnAnnotations[functionUpdatedAtAnnotation] = time.Now().UTC().Format(time.RFC3339)
|
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)
|
fn.SetAnnotations(fnAnnotations)
|
||||||
|
|
||||||
if err := unstructured.SetNestedField(fn.Object, map[string]any{
|
if err := unstructured.SetNestedField(fn.Object, map[string]any{
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
<div class="nubes">NUBES</div>
|
<div class="nubes">NUBES</div>
|
||||||
<div class="product">FISSION CONSOLE</div>
|
<div class="product">FISSION CONSOLE</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size:0.65rem; color:var(--text-secondary); margin-left:10px; align-self:center; opacity:0.7;">v1.3.49</div>
|
<div style="font-size:0.65rem; color:var(--text-secondary); margin-left:10px; align-self:center; opacity:0.7;">v1.3.50</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="margin:0;">
|
<div class="row" style="margin:0;">
|
||||||
<button class="btn ghost" onclick="reloadAll()">Refresh</button>
|
<button class="btn ghost" onclick="reloadAll()">Refresh</button>
|
||||||
@@ -462,7 +462,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions" style="justify-content:space-between; align-items:center;">
|
<div class="actions" style="justify-content:space-between; align-items:center;">
|
||||||
<span style="font-size:0.75rem; color:var(--text-secondary);">v1.3.49</span>
|
<span style="font-size:0.75rem; color:var(--text-secondary);">v1.3.50</span>
|
||||||
<button class="btn ghost" onclick="closeHelp()">Закрыть</button>
|
<button class="btn ghost" onclick="closeHelp()">Закрыть</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ async function openEdit(name) {
|
|||||||
if (fn.source_type === 'archive') {
|
if (fn.source_type === 'archive') {
|
||||||
setCodeMode('e', 'archive');
|
setCodeMode('e', 'archive');
|
||||||
var archiveNameEl = document.getElementById('e-archive-name');
|
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');
|
var archiveFile = document.getElementById('e-archive-file');
|
||||||
if (archiveFile) archiveFile.value = '';
|
if (archiveFile) archiveFile.value = '';
|
||||||
} else {
|
} else {
|
||||||
@@ -205,14 +205,16 @@ async function submitEdit() {
|
|||||||
// Обновляем через архив
|
// Обновляем через архив
|
||||||
var fd = new FormData();
|
var fd = new FormData();
|
||||||
fd.append('timeout', String(parseTimeout(document.getElementById('e-timeout').value)));
|
fd.append('timeout', String(parseTimeout(document.getElementById('e-timeout').value)));
|
||||||
|
fd.append('entrypoint', document.getElementById('e-entry').value.trim());
|
||||||
fd.append('archive', archiveFile);
|
fd.append('archive', archiveFile);
|
||||||
var resp = await fetch(API_BASE + '/functions/' + encodeURIComponent(name) + '/archive',
|
var resp = await fetch(API_BASE + '/functions/' + encodeURIComponent(name) + '/archive',
|
||||||
{ method: 'PUT', headers: authHeaders(), body: fd });
|
{ method: 'PUT', headers: authHeaders(), body: fd });
|
||||||
if (!resp.ok) { var e = await resp.json().catch(() => ({})); throw new Error(e.error || resp.statusText); }
|
if (!resp.ok) { var e = await resp.json().catch(() => ({})); throw new Error(e.error || resp.statusText); }
|
||||||
} else if (isArchiveMode) {
|
} else if (isArchiveMode) {
|
||||||
// Архив не заменяется — обновляем только timeout
|
// Архив не заменяется — обновляем только timeout + entrypoint
|
||||||
await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name) + '/timeout', 'PUT', {
|
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 {
|
} else {
|
||||||
await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name) + '/code', 'PUT', {
|
await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name) + '/code', 'PUT', {
|
||||||
|
|||||||
Reference in New Issue
Block a user