feat(job): merge sless_function into sless_job — self-contained build+run

- FunctionJobSpec: убран FunctionRef, добавлены Runtime/Entrypoint/Env/S3Key/MemoryMB/TimeoutSec
- FunctionJobStatus: новый ImageRef, новая фаза Building
- FunctionJobReconciler: Building фаза (kaniko), убрана зависимость от Function CRD
  Builder+OperatorNamespace как поля struct; аннотация sless.kube5s.ru/build-job guard
- main.go: Builder+OperatorNamespace переданы в FunctionJobReconciler
- jobs.go handler: jobRequest/jobResponse без FunctionRef; новый UploadJobCode handler
- router.go: /jobs/{name}/upload маршрут
- client.go: JobRequest/JobResponse обновлены; UploadJobCode; uploadCodeToURL общий хелпер
- job_resource.go: полная переработка — источник/среда встроены в JobModel, ModifyPlan,
  Create с upload, wait_timeout_sec=900 по умолчанию (kaniko + выполнение)
- examples/POSTGRES/functions.tf: раскомментирован, sless_function удалён,
  sless_job самодостаточен (inline source_dir/runtime/entrypoint/env_vars)
This commit is contained in:
Naeel
2026-03-20 21:27:35 +03:00
parent 1b3c8376c0
commit 8ca8faedd1
12 changed files with 569 additions and 185 deletions
+25 -6
View File
@@ -298,6 +298,17 @@ func (c *Client) UploadCode(ctx context.Context, ns, name, zipPath string) error
// UploadCodeReader — загружает код из произвольного io.Reader (например in-memory zip).
// filename используется только как имя файла в multipart-форме.
func (c *Client) UploadCodeReader(ctx context.Context, ns, name, filename string, r io.Reader) error {
return c.uploadCodeToURL(ctx, fmt.Sprintf("%s/v1/namespaces/%s/functions/%s/upload", c.endpoint, ns, name), filename, r)
}
// UploadJobCode — POST /v1/namespaces/{ns}/jobs/{name}/upload
// Аналогично UploadCodeReader но для FunctionJob — запускает kaniko через FunctionJob CRD.
func (c *Client) UploadJobCode(ctx context.Context, ns, name, filename string, r io.Reader) error {
return c.uploadCodeToURL(ctx, fmt.Sprintf("%s/v1/namespaces/%s/jobs/%s/upload", c.endpoint, ns, name), filename, r)
}
// uploadCodeToURL — внутренний хелпер: пакует io.Reader в multipart и POST-ит по указанному URL.
func (c *Client) uploadCodeToURL(ctx context.Context, uploadURL, filename string, r io.Reader) error {
var buf bytes.Buffer
mw := multipart.NewWriter(&buf)
fw, err := mw.CreateFormFile("code", filename)
@@ -309,8 +320,7 @@ func (c *Client) UploadCodeReader(ctx context.Context, ns, name, filename string
}
mw.Close()
url := fmt.Sprintf("%s/v1/namespaces/%s/functions/%s/upload", c.endpoint, ns, name)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, &buf)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, uploadURL, &buf)
if err != nil {
return err
}
@@ -428,10 +438,17 @@ func (c *Client) UpdateTrigger(ctx context.Context, ns, name string, req Trigger
// --- Job CRUD ---
// JobRequest — тело POST /v1/namespaces/{ns}/jobs
// Изменено: 2026-03-20 (merge: убран FunctionRef, добавлены Runtime/Entrypoint/Env)
type JobRequest struct {
Name string `json:"name"`
FunctionRef string `json:"function"`
EventJSON string `json:"event_json,omitempty"`
Name string `json:"name"`
Runtime string `json:"runtime"`
Entrypoint string `json:"entrypoint"`
MemoryMB int32 `json:"memory_mb,omitempty"`
TimeoutSec int32 `json:"timeout_sec,omitempty"`
Env map[string]string `json:"env_vars,omitempty"`
S3Bucket string `json:"s3_bucket,omitempty"`
S3Key string `json:"s3_key,omitempty"`
EventJSON string `json:"event_json,omitempty"`
// RunID: 0 = создать без запуска, >0 = запустить
RunID int64 `json:"run_id"`
}
@@ -440,10 +457,12 @@ type JobRequest struct {
type JobResponse struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
FunctionRef string `json:"function"`
Runtime string `json:"runtime"`
Entrypoint string `json:"entrypoint"`
EventJSON string `json:"event_json"`
RunID int64 `json:"run_id"`
Phase string `json:"phase"`
ImageRef string `json:"image_ref"`
JobName string `json:"job_name"`
StartTime string `json:"start_time"`
CompletionTime string `json:"completion_time"`