Function Inline Source 物化

状态:已接受;API 与通用 source preparation 已完成

function-mode Run 可以使用 repository source 或 inline source。repository source 会保留原有 文件布局;当前 inline source 不会:runtimed 会将其写到固定的 script 文件。对于由 runtime 定义、并通过文件或 module 标识的 handler,这并不足够,例如 Python app.invoke 或 Bash handler.handle

本文定义一个最小 API,使单个 inline function source 能以可预测的文件路径物化,同时不让 runtimed 理解具体 runtime 的语言。

API

Run.spec.source 增加 inlinePath

type CodeSource struct {
    Inline     *string `json:"inline,omitempty"`
    InlinePath string `json:"inlinePath,omitempty"`
    RepoURL    string `json:"repoURL,omitempty"`
    CommitSHA  string `json:"commitSHA,omitempty"`
}

第一版中,inlinePath 只允许在 function-mode Run 中使用;当 function-mode Run 设置了 source.inline 时它必须存在。它表示 runtimed 在准备后的 Run working directory 下写入 inline source 的相对路径。

apiVersion: kruntimes.io/v1alpha1
kind: Run
metadata:
  name: kube-diagnose-agent
spec:
  runtime: python
  source:
    inlinePath: app.py
    inline: |
      def invoke(request):
          return {"summary": "diagnosis complete"}
  mode:
    function:
      handler: app.invoke

同一机制也适用于 Bash function runtime:

spec:
  runtime: bash
  source:
    inlinePath: handler.sh
    inline: |
      handle() {
        printf '%s\n' "$1"
      }
  mode:
    function:
      handler: handler.handle

inlinePath 只描述 source 的物化方式。handler 仍然是由 runtime 定义的 callable entrypoint。runtimed 负责验证路径,但不推断语言相关扩展名,也不试图验证它是否和 handler 匹配。Runtime Server 仍负责验证和加载其 handler 格式。

验证与准备

inlinePath 被要求时,它必须是非空的相对文件路径。验证必须拒绝绝对路径、... path segment、空 basename 以及超过 4096 bytes 的值。runtimed 必须只在准备后的 working directory 下创建父目录,并将 inline 内容写到已验证的路径。

本提案不改变 task-mode inline 的语义:未使用 function mode 时,inline source 继续写到已有的 默认 script 文件。task-mode Run 上的 inlinePath 会被拒绝,避免它和 mode.task.entrypoint 产生歧义。

一份 inline source 只表示一个文件。需要 package、多个文件、生成的依赖或其他 repository 布局的 function,应使用 source.git 或引用 persistent workspace。

为什么采用这个边界

在 runtimed 中根据 handler 推断 app.pyhandler.sh,会把共享 source-preparation 层和 内置 runtime 的约定耦合起来,并阻止 custom runtime 定义自己的 handler 格式。限制 function mode 只能使用 repository source,又会使最常见的小型 function 场景不必要地复杂。

显式路径使 source contract 保持通用,也让用户可以直接看出生成后的文件布局。同时,在 task process-start 语义经过单独 API review 前,它不会改变 task 的行为。

后续实现

API field、CEL validation、generated deepcopy code、CRD manifests 和通用 source preparation 已完成。剩余实现为:

  1. 更新 function 示例和 Python、Bash、repository、invalid-path 的 validation tests;
  2. 实现从 ScheduledReady 的 function registration lifecycle。