Documentation
¶
Overview ¶
Package engine 是 fleetly 发布引擎(task-breakdown T2.10 发布状态机与 对账核心 + T2.11 窗口与失败语义):compose → 放置/env/镜像/secret 准备 → Swarm service 对账(新增/更新/删除)→ 健康门 → 观察窗 → 版本固化,以及 失败分流(归位/首发 scale=0/已切流告警)、L2 看门狗与 L3 观察窗、控制面 重启分类恢复、cancel 与 app 派生状态。
设计真源(逐条对齐,不改语义):
- docs/design/2026-09-17-release-semantics.md(§2.1 四不变量、§2.2 窗口 模型、§2.3 状态机、§2.4 快照与归位、§2.5 场景矩阵 1-16、§2.6 stop-first 专表、§2.7 错误码/事件/审计、§2.8 治理参数)
- docs/design/2026-09-17-architecture.md §2.4/§2.5(受管字段固定 failure_action=pause、monitor=5s;省略=删除;env 三层合并随部署生效)
- docs/design/2026-09-17-state-model.md §2.10(app 派生状态优先级)
结构纪律(架构 §2.8):核心不出现第三方类型——Swarm 服务/任务面经本包 定义的端口(Substrate)访问,moby 类型只存在于 internal/substrate 的实现 内;状态写走 internal/state(事务内事件+审计 fail-closed)。
观测纪律(Spike B 硬经验):Engine 29.x docker events 无 task 事件—— 状态机推进一律走 service/task API 轮询(poll tick),订阅流只作观测缓存 失效信号(internal/state.Observer,与本引擎无关)。归位重放禁用 --force (Spike B2:同内容重放任务零替换的零成本归位依赖它)。
Index ¶
- Constants
- Variables
- func CanTransition(from, to Phase) bool
- func DeriveAppState(f AppFacts) string
- func EnqueueRollback(ctx context.Context, st *state.Store, in RollbackInput) (state.DeployRecord, error)
- func Transition(from, to Phase) error
- type AppFacts
- type Clock
- type Config
- type DriftReport
- type Engine
- func (e *Engine) AppDerivedState(ctx context.Context, appID string) (string, error)
- func (e *Engine) CancelRequest(ctx context.Context, rec state.DeployRecord) error
- func (e *Engine) ConvergeApp(ctx context.Context, appName, actor string) (state.DeployRecord, error)
- func (e *Engine) DriftScan(ctx context.Context)
- func (e *Engine) DriftShow(ctx context.Context, appName string) (*DriftReport, error)
- func (e *Engine) GetDriftConverge(ctx context.Context, appName string) (bool, error)
- func (e *Engine) ReapDeletingApps(ctx context.Context)
- func (e *Engine) Run(ctx context.Context) error
- func (e *Engine) SetDriftConverge(ctx context.Context, appName string, on bool, actor string) error
- func (e *Engine) SubstrateRecon(ctx context.Context)
- func (e *Engine) Tick(ctx context.Context)
- func (e *Engine) WithClock(c Clock) *Engine
- func (e *Engine) WithEnvChangedHook(fn EnvChangedHook) *Engine
- func (e *Engine) WithPostDeployHook(fn PostDeployHook) *Engine
- func (e *Engine) WithRoutePublisher(p RoutePublisher) *Engine
- type EnvChangedHook
- type ErrIllegalTransition
- type FieldDiff
- type HealthcheckSpec
- type ImageChecker
- type MountSpec
- type NetworkAttach
- type Phase
- type PlacementResolver
- type Plan
- type PlanInput
- type PostDeployHook
- type ResourcesSpec
- type RestartPolicySpec
- type RollbackInput
- type RoutePublishInput
- type RoutePublisher
- type RouteServiceSpec
- type SecretMount
- type ServiceDrift
- type ServiceSpec
- type ServiceState
- type Substrate
- type TaskState
Constants ¶
const ( PhaseQueued Phase = "queued" PhasePreparing Phase = "preparing" PhaseBuilding Phase = "building" PhaseReleasing Phase = "releasing" PhaseObserving Phase = "observing" PhaseSucceeded Phase = "succeeded" PhaseFailed Phase = "failed" PhaseCancelled Phase = "cancelled" // PhaseNone 是子状态空值(无子状态)。 PhaseNone string = "" )
const ( DerivedRunning = "running" DerivedDegraded = "degraded" DerivedBlocked = "blocked" DerivedDown = "down" )
派生状态词表(state 词表对齐:running/degraded/blocked/down)。
const (
SubBlockedWaiting = "blocked_waiting"
)
SubPhase 是 releasing 内的子状态(blocked_waiting,场景 15)。
Variables ¶
var ( ErrServiceNotFound = errors.New("substrate service not found") // ErrNotSwarmReady 表示引擎未启用 Swarm(或本机非 active manager)。 ErrNotSwarmReady = errors.New("docker engine is not an active swarm manager") )
ErrServiceNotFound / ErrNotSwarmReady 是端口哨兵(适配器归一)。
var ErrImageMissing = errors.New("image not available on local daemon")
ErrImageMissing 表示镜像本机不可得(preflight → E_IMAGE_PULL_FAILED)。
var LabelBookkeeping = map[string]bool{ state.LabelDeployment: true, state.LabelDesiredHash: true, }
LabelBookkeeping 是漂移投影剔除的平台簿记 label 键:deployment 归属随 每次部署/回滚合法变化;desired-hash 本身就是被比对的量(写前才落 label) ——两者都不是用户可见期望态。
Functions ¶
func CanTransition ¶
CanTransition 报告 from → to 是否合法转移(委托 state 权威转移表)。
func DeriveAppState ¶
DeriveAppState 是纯函数裁决:down > blocked > degraded > running。
- down:首发失败 scale=0(substrate_halted),或无有效版本且最近一次 失败未切流(没有任何期望实例——归位为零动作/scale 0);
- blocked:placement.state ∈ {blocked, unresolved}(绑定不可用/已移除);
- degraded:观察窗失败(verdict=unstable——含首发已切流后失败的形态, 新版本仍在服务)/ 窗后不稳定 / 警告通过(W_DEPLOY_INSTABILITY);
- running:以上皆否。
func EnqueueRollback ¶
func EnqueueRollback(ctx context.Context, st *state.Store, in RollbackInput) (state.DeployRecord, error)
EnqueueRollback 解析回滚目标并入队 kind=rollback 部署(CLI 入口;与 deploy 同拓扑——入队与执行跨进程解耦,执行由 fleetlyd 引擎扫描推进)。 目标解析失败(app 不存在 / revision 越界或被保留窗淘汰 / 源部署快照 缺失)→ E_ROLLBACK_NO_TARGET。
func Transition ¶
Transition 校验 from → to 合法,非法返回 *ErrIllegalTransition。
Types ¶
type AppFacts ¶
type AppFacts struct {
// PlacementState 是绑定状态位(” = 无绑定记录——自由调度非 blocked)。
PlacementState string
// Latest 是最近一条部署记录(零值 = 无部署)。
Latest state.DeployRecord
// LatestSucceeded 是最近一条 succeeded 部署(零值 = 无有效版本)。
LatestSucceeded state.DeployRecord
}
AppFacts 是派生裁决的输入事实。
type Config ¶
type Config struct {
// DeployTimeout 是 L2 看门狗预算(默认 300s;有效值 ≥ health 预算)。
DeployTimeout time.Duration
// ObserveWindow 是 L3 观察窗时长(默认 60s)。
ObserveWindow time.Duration
// UnstableReplicasBelow 是副本水位的持续不足判定时长(默认 10s,
// release-semantics §2.2 L3 信号)。
ReplicasBelowFor time.Duration
// PollInterval 是引擎轮询周期(默认 2s)。
PollInterval time.Duration
// DriftInterval 是运行域漂移检测扫描周期(默认 30s,可配
// engine.drift_interval_seconds;D11:检测默认开)。
DriftInterval time.Duration
}
Config 是引擎治理参数(release-semantics §2.8:v0.1 平台默认;config 节 仅作部署面覆盖入口,文件缺省即文档默认)。
type DriftReport ¶
type DriftReport struct {
App string `json:"app"`
// DesiredDeployment 是期望态来源部署(空 = 无成功部署记录,无从判定)。
DesiredDeployment string `json:"desired_deployment,omitempty"`
Drifted bool `json:"drifted"`
Services []ServiceDrift `json:"services,omitempty"`
}
DriftReport 是一次漂移检测报告。
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine 是发布引擎。依赖里的 *secrets.Box 承担两件事:平台 env 密文解密 (合并输入)与期望态快照加密(desired_spec——归位/重放的执行依据,明文 纪律与 env_vars 相同:只以密文落库)。
func NewEngine ¶
func NewEngine(cfg Config, store *state.Store, sub Substrate, images ImageChecker, resolver PlacementResolver, box *secrets.Box, log *slog.Logger) *Engine
NewEngine 构造发布引擎(时钟缺省真实时钟;水位表初始化)。
func (*Engine) AppDerivedState ¶
AppDerivedState 是读面出口(CLI deploy 结果输出用)。
func (*Engine) CancelRequest ¶
CancelRequest 是 CLI 的取消入口:准入预检(曾健康 → 409 信封)+ 请求位 置位(引擎消费执行归位)。
func (*Engine) ConvergeApp ¶
func (e *Engine) ConvergeApp(ctx context.Context, appName, actor string) (state.DeployRecord, error)
ConvergeApp 人工一次性收敛(CLI 入口):按当前期望态(最近 succeeded deployment 快照)执行归位重放原语并写审计。在途部署存在时拒绝 (409 语义——发布本身就是收敛过程)。
func (*Engine) GetDriftConverge ¶
GetDriftConverge 读取收敛 opt-in 位(CLI show 面)。
func (*Engine) ReapDeletingApps ¶
ReapDeletingApps 单步执行 deleting 应用回收扫描(测试与诊断显式入口—— 直通频控闸;生产由 tick 周期驱动)。
func (*Engine) Run ¶
Run 启动引擎主循环:启动扫描(控制面重启分类恢复)→ 周期 tick + 漂移 扫描。ctx 取消返回 nil(lynx actor 契约由服务壳负责阻塞语义)。
func (*Engine) SetDriftConverge ¶
SetDriftConverge 置位/清除收敛 opt-in(人工重置入口;带审计,actor 透传)。
func (*Engine) SubstrateRecon ¶
SubstrateRecon 单步执行存在性对账扫描(测试与诊断显式入口——直通频控 闸;生产由 tick 周期驱动)。
func (*Engine) WithEnvChangedHook ¶
func (e *Engine) WithEnvChangedHook(fn EnvChangedHook) *Engine
WithEnvChangedHook 注入 env 变更挂钩(H9:pending env 提升点触发日志 脱敏值集失效——装配层接到 logs.Manager.InvalidateRedaction。挂钩同步 执行,实现必须非阻塞(实现方只做缓存删除),失败不得影响部署终态)。
func (*Engine) WithPostDeployHook ¶
func (e *Engine) WithPostDeployHook(fn PostDeployHook) *Engine
WithPostDeployHook 注入部署成功挂钩(T2.22 备份触发面:每次部署成功后 一次热备快照。引擎侧异步触发——go 例程 + 独立预算在实现方;挂钩失败 只落备份台账与告警,绝不回滚/阻塞已成功的部署)。
func (*Engine) WithRoutePublisher ¶
func (e *Engine) WithRoutePublisher(p RoutePublisher) *Engine
WithRoutePublisher 注入发布器(链式;nil 显式表示不发布)。
type EnvChangedHook ¶
type EnvChangedHook func(appID string)
EnvChangedHook 是 env 生效/变更后的联动挂钩签名(载荷 = appID;H9)。
type ErrIllegalTransition ¶
ErrIllegalTransition 表示非法状态转移(含终态出边)。
func (*ErrIllegalTransition) Error ¶
func (e *ErrIllegalTransition) Error() string
type FieldDiff ¶
type FieldDiff struct {
Field string `json:"field"`
Expected string `json:"expected"`
Actual string `json:"actual"`
}
FieldDiff 是一个字段的差异条目(值均为投影形态:env 只到键名 + hash)。
type HealthcheckSpec ¶
type HealthcheckSpec struct {
Test []string `json:"test"`
Interval time.Duration `json:"interval"`
Timeout time.Duration `json:"timeout"`
Retries uint64 `json:"retries"`
StartPeriod time.Duration `json:"start_period"`
}
HealthcheckSpec 是健康检查(平台缺省 5s/3s/3/10s 由规划层补齐——治理 参数取当前平台配置,release-semantics §2.4)。
type ImageChecker ¶
type ImageChecker interface {
// ImageDigest 返回镜像本机 ID(`sha256:<hex>`);缺失返回
// ErrImageMissing。
ImageDigest(ctx context.Context, ref string) (string, error)
}
镜像可见性端口(复用 build 层端口形态;适配器同源)。
type MountSpec ¶
type MountSpec struct {
// VolumeName 是平台卷注册表的 docker 卷名(fleetly-<app>-<key>-<id8>)。
VolumeName string `json:"volume"`
Target string `json:"target"`
ReadOnly bool `json:"read_only,omitempty"`
}
MountSpec 是一次命名卷挂载。
type NetworkAttach ¶
type NetworkAttach struct {
Name string `json:"name"`
// Aliases 是网络内别名(= compose 服务名,app 内短名互访)。
Aliases []string `json:"aliases,omitempty"`
}
NetworkAttach 是一次服务网络接入。
type Phase ¶
type Phase string
Phase 是状态机主状态(与 state.DeploymentStatus 同词表;本包自有常量 避免引擎→state 的枚举反向依赖——行写入时按字符串落库)。
func LegalTransitions ¶
LegalTransitions 返回 from 的合法目标集合(穷举测试断言用;from 为终态 或未知状态返回空)。
type PlacementResolver ¶
type PlacementResolver interface {
Resolve(ctx context.Context, in placement.Input) (placement.Decision, error)
Apply(ctx context.Context, in placement.Input) (placement.Decision, error)
Preflight(ctx context.Context, appID string) error
}
PlacementResolver 是引擎对放置层的消费端口(internal/placement.Resolver 隐式实现;接口在本包定义以便单测注入)。
type Plan ¶
type Plan struct {
// Services 按服务名字典序(对账与快照确定性)。
Services []ServiceSpec
// EnvSnapshotHash 是 env 三层合并结果快照哈希(key:sha256+来源;
// 值明文永不进哈希输入)。
EnvSnapshotHash string
// DesiredHash 是部署级期望态哈希(spec + env + 各服务哈希合成)。
DesiredHash string
// DesiredSpecJSON 是 []ServiceSpec 的 canonical JSON(密文化的快照明文
// 形态——归位/重放的执行依据)。
DesiredSpecJSON []byte
// Warnings 是规划期警告(W_ENV_PLATFORM_OVERRIDE 等)。
Warnings []compose.Warning
}
Plan 是一次期望态规划产出。
type PlanInput ¶
type PlanInput struct {
AppID string
AppName string
// DeploymentID 是发布归属(服务 label fleetly.deployment)。
DeploymentID string
// Spec 是归一化 compose(daemon 侧重载,二次校验防御)。
Spec *compose.Spec
// FileEnv / ComposeEnv 是 services.* 的文件层明文(extractServiceEnvs)。
FileEnv map[string]map[string]string
ComposeEnv map[string]map[string]string
// PlatformEnv 是已生效(effective)平台 env(三层合并的第三层输入;
// pending 不参与合并——「随下次部署生效」由部署成功后的 promote 承载)。
PlatformEnv []envlayer.PlatformVar
// Images 是服务 → digest 钉定镜像引用(building 阶段产出)。
Images map[string]string
// Decision 是放置裁决(绑定约束编译结果)。
Decision placement.Decision
Volumes []state.Volume
}
PlanInput 是一次期望态规划的输入(preparing 阶段收集齐)。
type PostDeployHook ¶
type PostDeployHook func(rec state.DeployRecord)
PostDeployHook 是部署成功后的备份挂钩签名(rec 为成功部署记录的副本)。
type ResourcesSpec ¶
type ResourcesSpec struct {
NanoCPUs int64 `json:"nano_cpus,omitempty"`
MemoryBytes int64 `json:"memory_bytes,omitempty"`
}
ResourcesSpec 是资源限额(仅 limits;cpus 以 nano CPUs 计)。
type RestartPolicySpec ¶
type RestartPolicySpec struct {
Condition string `json:"condition"`
Delay time.Duration `json:"delay,omitempty"`
MaxAttempts uint64 `json:"max_attempts,omitempty"`
Window time.Duration `json:"window,omitempty"`
}
RestartPolicySpec 是重启策略(architecture §2.5:缺省 condition=any、 delay=5s——Swarm 重启自愈语义)。
type RollbackInput ¶
type RollbackInput struct {
// AppName 是 compose 应用名。
AppName string
// TargetRevisionID 是回滚目标版本快照;空 = 最近一次成功部署的版本
//(`fleetly rollback <app>` 缺省回退一版)。
TargetRevisionID string
// Actor 是审计操作主体(human/ai_agent;CLI 直连为 human)。空按
// human 兜底(审计列非空约束)。
Actor string
}
RollbackInput 是一次回滚入队的请求。
type RoutePublishInput ¶
type RoutePublishInput struct {
AppID string
AppName string
Services []RouteServiceSpec
}
RoutePublishInput 是一次路由发布输入。
type RoutePublisher ¶
type RoutePublisher interface {
PublishRoutes(ctx context.Context, in RoutePublishInput) error
}
RoutePublisher 是入口路由发布端口(internal/ingress.Manager 隐式实现; 接口在本包定义以便单测注入假发布器)。nil = 未接入口面(无域名部署 或单测环境,发布逻辑整体跳过)。
type RouteServiceSpec ¶
type RouteServiceSpec struct {
Service string
// Port 是后端端口(compose expose 首端口)。
Port string
// Domains 是归一化域名集。
Domains []string
}
RouteServiceSpec 是单个入口服务的路由声明(引擎 → 发布端口的载荷)。
type SecretMount ¶
type SecretMount struct {
// SecretName 是 Swarm secret 名(fleetly-<app>-<name>-<hash8>)。
SecretName string `json:"secret"`
// Target 是容器内挂载文件路径(/run/secrets/<compose 名>)。
Target string `json:"target"`
}
SecretMount 是一次 Swarm secret 文件挂载。
type ServiceDrift ¶
type ServiceDrift struct {
Service string `json:"service"`
Drifted bool `json:"drifted"`
Missing bool `json:"missing,omitempty"`
Extra bool `json:"extra,omitempty"`
Diff []FieldDiff `json:"diff,omitempty"`
}
ServiceDrift 是单个服务的漂移结果。
type ServiceSpec ¶
type ServiceSpec struct {
// Name 是 Swarm 服务名(fleetly-<app>-<service>,naming.ServiceName)。
Name string `json:"name"`
// Image 是 digest 钉定引用(`repo@sha256:...`,D9)。
Image string `json:"image"`
Command []string `json:"command,omitempty"`
// Env 是合并后的注入环境(KEY=VALUE,按 key 字典序;值明文只存活于
// 本结构与密文快照,不进日志/事件/审计)。
Env []string `json:"env,omitempty"`
// ServiceLabels 是服务级 label(naming.ServiceLabels 最小集 +
// fleetly.desired-hash;service-label 变更不触发任务重建,Spike B2)。
ServiceLabels map[string]string `json:"service_labels,omitempty"`
// ContainerLabels 是任务容器 label(naming.ContainerLabels:仅
// fleetly.app——跨部署稳定,归位零任务替换的前提,Spike B2)。
ContainerLabels map[string]string `json:"container_labels,omitempty"`
// Global 是 global 模式(compose deploy.mode=global);false = replicated。
Global bool `json:"global,omitempty"`
// Replicas 是期望副本(replicated 模式;0 = scale-0 保留现场)。
Replicas uint64 `json:"replicas"`
// Networks 是服务接入网络(per-app 专属网络 + 别名 = compose 服务名)。
Networks []NetworkAttach `json:"networks,omitempty"`
// Mounts 是命名卷挂载(docker 卷名经卷注册表映射)。
Mounts []MountSpec `json:"mounts,omitempty"`
// Secrets 是 Swarm secret 挂载(file target = compose 名)。
Secrets []SecretMount `json:"secrets,omitempty"`
// Healthcheck 为 nil = health_gate=none(健康门退化为退出/副本水位)。
Healthcheck *HealthcheckSpec `json:"healthcheck,omitempty"`
// UpdateOrder 是更新顺序(start-first 默认;有卷/固定端口/global 强制
// stop-first——组合裁决在规划层,适配器照用)。
UpdateOrder string `json:"update_order"`
// UpdateParallelism / UpdateDelay 照用 compose(parallelism 缺省 1)。
UpdateParallelism uint64 `json:"update_parallelism"`
UpdateDelay time.Duration `json:"update_delay,omitempty"`
// RestartPolicy 为 nil 时适配器补平台缺省(condition=any / delay=5s,
// architecture §2.5 运行期语义)。
RestartPolicy *RestartPolicySpec `json:"restart_policy,omitempty"`
Resources *ResourcesSpec `json:"resources,omitempty"`
// Constraints 是放置约束(绑定钉住编译 + compose 声明的
// node.labels.fleetly.* 约束)。
Constraints []string `json:"constraints,omitempty"`
StopSignal string `json:"stop_signal,omitempty"`
// StopGracePeriod ≤0 = 底座缺省(compose stop_grace_period 照用)。
StopGracePeriod time.Duration `json:"stop_grace_period,omitempty"`
}
ServiceSpec 是一次目标服务形态(引擎期望态的执行投影;canonical JSON 序列化后参与 desired-hash——与底座 spec 深度对齐的字段集,受管字段 failure_action=pause/monitor=5s 由适配器固定补齐,不进本结构与哈希)。
func (ServiceSpec) DesiredHash ¶
func (s ServiceSpec) DesiredHash() string
DesiredHash 计算期望态哈希(对账变更判据,state-model §2.5 desired-hash 纪律:廉价、稳定、不泄露 env——哈希输入是全字段 canonical JSON,落库与 label 的只是哈希)。服务级 label 不参与(含部署 ID——归位重放时服务 label 更新不触发任务替换,Spike B2;container label 参与且跨部署稳定)。
type ServiceState ¶
type ServiceState struct {
Name string
// Version 是底座对象版本(乐观令牌;诊断用——服务写经适配器内部取版
// 本,引擎不做跨调用令牌传递,避免写前直读令牌陈旧化)。
Version uint64
Labels map[string]string
// DesiredHash 是服务 label 里的期望态哈希(” = 非平台写或旧形态)。
DesiredHash string
// Image 是当前 spec 镜像引用。
Image string
// Replicas 是期望副本数(replicated;global 服务为 0)。
Replicas uint64
// UpdateState / UpdateMessage 逐字镜像底座 UpdateStatus
//(”/updating/paused/completed,Spike B:更新失败归 paused+Message)。
UpdateState string
UpdateMessage string
// ── 运行域漂移反解字段(T2.13;与 ServiceSpec 同构,由适配器填充)──
Command []string
Env []string
ContainerLabels map[string]string
Global bool
Networks []NetworkAttach
Mounts []MountSpec
Secrets []SecretMount
Healthcheck *HealthcheckSpec
RestartPolicy *RestartPolicySpec
Resources *ResourcesSpec
Constraints []string
StopSignal string
StopGracePeriod time.Duration
// ── S18-A8:Spec.UpdateConfig 投影补齐(外部 docker service update
// --update-* 篡改的判定面)。Order/Parallelism/Delay 三字段随
// serviceSpecOf 进漂移哈希;FailureAction 是平台受管字段(适配器固定
// pause,不进 ServiceSpec/哈希),篡改走 drift 的专报项。──
UpdateOrder string
UpdateParallelism uint64
UpdateDelay time.Duration
UpdateFailureAction string
}
ServiceState 是一次 Swarm 服务实况投影(对账/健康门观测输入;T2.13 起 兼作运行域漂移反解载体——spec 侧字段由适配器从 swarm.Service.Spec 逐字 抄出,漂移投影只取 state-model §2.5 受控子集字段,env 值只进 sha256 不 出端口消费面)。
type Substrate ¶
type Substrate interface {
// SwarmReady 确认本机为 active swarm manager;未 init 返回可判别错误
//(errors.Is(err, ErrNotSwarmReady))。
SwarmReady(ctx context.Context) error
// NetworkEnsure 确认 overlay 网络存在(幂等;缺失创建)。
NetworkEnsure(ctx context.Context, name string) error
// ServiceInspect 按名取服务实况;缺失返回 ErrServiceNotFound。
ServiceInspect(ctx context.Context, name string) (ServiceState, error)
// ServiceCreate 创建服务(幂等性由调用方对账保证:仅缺失时调用)。
ServiceCreate(ctx context.Context, spec ServiceSpec) error
// ServiceUpdate 以乐观令牌推进服务到目标形态。适配器内部读版本并短
// 重试并发冲突;ForceUpdate 恒不递增(归位零成本纪律,Spike B2)。
ServiceUpdate(ctx context.Context, name string, spec ServiceSpec) error
// ServiceRemove 删除服务(省略=删除语义;幂等:缺失视为成功)。
ServiceRemove(ctx context.Context, name string) error
// ServiceList 按 label 选择器返回服务(managed+app 前缀过滤)。
ServiceList(ctx context.Context, labels map[string]string) ([]ServiceState, error)
// TaskList 返回服务的全部任务(含历史;观测轮询的数据源)。
TaskList(ctx context.Context, service string) ([]TaskState, error)
}
Substrate 是底座服务/任务面端口(internal/substrate.Client 隐式实现)。
type TaskState ¶
type TaskState struct {
ID string
Slot int
// State 逐字镜像底座任务状态(new/pending/running/failed/complete/
// shutdown/rejected/...)。
State string
// DesiredState 是期望态(running/remove/...)——旧任务下线判据。
DesiredState string
// Err 是任务失败原因(逐字;health 判定归 E_HEALTH_TIMEOUT 的来源)。
Err string
// Timestamp 是任务状态时间戳。
Timestamp time.Time
// Image 是任务 spec 镜像引用(新旧版本判据:与目标 digest 比对)。
Image string
}
TaskState 是一次任务实况投影(service ps 轮询;Spike B 观测纪律)。